mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
commit
7169925a4e
21
libesp32/ESP32-Mail-Client/LICENSE
Executable file
21
libesp32/ESP32-Mail-Client/LICENSE
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 mobizt
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
2138
libesp32/ESP32-Mail-Client/README.md
Executable file
2138
libesp32/ESP32-Mail-Client/README.md
Executable file
File diff suppressed because it is too large
Load Diff
278
libesp32/ESP32-Mail-Client/examples/Receive_email/Receive_email.ino
Executable file
278
libesp32/ESP32-Mail-Client/examples/Receive_email/Receive_email.ino
Executable file
@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
* Created by K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
* Email: k_suwatchai@hotmail.com
|
||||||
|
*
|
||||||
|
* Github: https://github.com/mobizt
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 mobizt
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1
|
||||||
|
|
||||||
|
//To receive Email for Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========================================================================================================================
|
||||||
|
To prevent stack overrun in case of you want to download email attachments in IMAP readMail,
|
||||||
|
increase the stack size in app_main() in esp32 main.cpp will help by change the stack size from 8192 to any more value
|
||||||
|
as following
|
||||||
|
|
||||||
|
xTaskCreatePinnedToCore(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
|
||||||
|
to
|
||||||
|
xTaskCreatePinnedToCore(loopTask, "loopTask", 16384, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
|
||||||
|
|
||||||
|
For Arduino, file esp32's main.cpp is at C:\Users\USER_NAME\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1\cores\esp32\main.cpp
|
||||||
|
And for platformIO, that file is at C:\Users\USER_NAME\.platformio\packages\framework-arduinoespressif32\cores\esp32\main.cpp
|
||||||
|
===========================================================================================================================
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "ESP32_MailClient.h"
|
||||||
|
#include "SD.h"
|
||||||
|
|
||||||
|
#define WIFI_SSID "YOUR_WIFI_SSID"
|
||||||
|
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//The Email Reading data object contains config and data that received
|
||||||
|
IMAPData imapData;
|
||||||
|
|
||||||
|
//Callback function to get the Email reading status
|
||||||
|
void readCallback(ReadStatus info);
|
||||||
|
|
||||||
|
//List all files in SD card
|
||||||
|
void printDirectory(File &dir, int depth);
|
||||||
|
|
||||||
|
void readEmail();
|
||||||
|
|
||||||
|
unsigned long lastTime = 0;
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("Connecting to AP");
|
||||||
|
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||||
|
while (WiFi.status() != WL_CONNECTED)
|
||||||
|
{
|
||||||
|
Serial.print(".");
|
||||||
|
delay(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("WiFi connected.");
|
||||||
|
Serial.println("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
MailClient.sdBegin();
|
||||||
|
//MailClient.sdBegin(14,2,15,13); //SCK, MISO, MOSI,SS for TTGO T8 v1.7 or 1.8
|
||||||
|
|
||||||
|
File dir = SD.open("/");
|
||||||
|
|
||||||
|
printDirectory(dir, 0);
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
imapData.setLogin("imap.gmail.com", 993, "YOUR_EMAIL_ACCOUNT@gmail.com", "YOUR_EMAIL_PASSWORD");
|
||||||
|
imapData.setFolder("INBOX");
|
||||||
|
|
||||||
|
//Clear fetch UID
|
||||||
|
//If fetch UID was set, no search is perform.
|
||||||
|
imapData.setFetchUID("");
|
||||||
|
|
||||||
|
//imapData.setSearchCriteria("UID SINCE 10-Feb-2019");
|
||||||
|
//imapData.setSearchCriteria("UID 700:*");
|
||||||
|
//imapData.setSearchCriteria("UID SEARCH NOT SEEN");
|
||||||
|
//imapData.setSearchCriteria("UID SEARCH UNSEEN");
|
||||||
|
imapData.setSearchCriteria("UID SEARCH ALL");
|
||||||
|
|
||||||
|
//To fetch or read one message UID = 320
|
||||||
|
//imapData.setFechUID("320");
|
||||||
|
|
||||||
|
//Set SD folder to save download messages and attachments
|
||||||
|
imapData.setSaveFilePath("/email_data");
|
||||||
|
|
||||||
|
//Save attachament
|
||||||
|
imapData.setDownloadAttachment(true);
|
||||||
|
|
||||||
|
//Set fetch/search result to return html message
|
||||||
|
imapData.setHTMLMessage(true);
|
||||||
|
|
||||||
|
//Set fetch/search result to return text message
|
||||||
|
imapData.setTextMessage(true);
|
||||||
|
|
||||||
|
//Set to save html message in SD card with decoded content.
|
||||||
|
imapData.saveHTMLMessage(true, true);
|
||||||
|
|
||||||
|
//Set to save text message in SD card with decoded content.
|
||||||
|
imapData.saveTextMessage(true, true);
|
||||||
|
|
||||||
|
//Set the maximum result when search criteria was set.
|
||||||
|
imapData.setSearchLimit(10);
|
||||||
|
|
||||||
|
//Set the sort order of returning message upon most recent received email.
|
||||||
|
imapData.setRecentSort(true);
|
||||||
|
|
||||||
|
//Set the return tex/html message size in byte.
|
||||||
|
imapData.setMessageBufferSize(200);
|
||||||
|
|
||||||
|
//Set the maximum attachment size 5 MB (each file)
|
||||||
|
imapData.setAttachmentSizeLimit(1024 * 1024 * 5);
|
||||||
|
|
||||||
|
//Set the Email receive callback function.
|
||||||
|
imapData.setReadCallback(readCallback);
|
||||||
|
|
||||||
|
//Set to get attachment downloading progress status.
|
||||||
|
imapData.setDownloadReport(true);
|
||||||
|
|
||||||
|
//Set the storage types to save download attachments or messages (SD is default)
|
||||||
|
//imapData.setFileStorageType(MailClientStorageType::SPIFFS)
|
||||||
|
imapData.setFileStorageType(MailClientStorageType::SD);
|
||||||
|
|
||||||
|
MailClient.readMail(imapData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void readEmail()
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Read Email...");
|
||||||
|
|
||||||
|
imapData.setFetchUID("10");
|
||||||
|
imapData.setSearchCriteria("");
|
||||||
|
MailClient.readMail(imapData);
|
||||||
|
|
||||||
|
imapData.setFetchUID("11");
|
||||||
|
imapData.setSearchCriteria("");
|
||||||
|
MailClient.readMail(imapData);
|
||||||
|
|
||||||
|
imapData.setFetchUID("12");
|
||||||
|
imapData.setSearchCriteria("");
|
||||||
|
MailClient.readMail(imapData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (millis() - lastTime > 1000 * 60 * 3)
|
||||||
|
{
|
||||||
|
|
||||||
|
lastTime = millis();
|
||||||
|
Serial.println(ESP.getFreeHeap());
|
||||||
|
|
||||||
|
readEmail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Callback function to get the Email reading status
|
||||||
|
void readCallback(ReadStatus msg)
|
||||||
|
{
|
||||||
|
//Print the current status
|
||||||
|
Serial.println("INFO: " + msg.info());
|
||||||
|
|
||||||
|
if (msg.status() != "")
|
||||||
|
Serial.println("STATUS: " + msg.status());
|
||||||
|
|
||||||
|
//Show the result when reading finished
|
||||||
|
if (msg.success())
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < imapData.availableMessages(); i++)
|
||||||
|
{
|
||||||
|
Serial.println("=================");
|
||||||
|
|
||||||
|
//Search result number which varied upon search crieria
|
||||||
|
Serial.println("Messsage Number: " + imapData.getNumber(i));
|
||||||
|
|
||||||
|
//UID only available when assigned UID keyword in setSearchCriteria
|
||||||
|
//e.g. imapData.setSearchCriteria("UID SEARCH ALL");
|
||||||
|
Serial.println("Messsage UID: " + imapData.getUID(i));
|
||||||
|
Serial.println("Messsage ID: " + imapData.getMessageID(i));
|
||||||
|
Serial.println("Accept Language: " + imapData.getAcceptLanguage(i));
|
||||||
|
Serial.println("Content Language: " + imapData.getContentLanguage(i));
|
||||||
|
Serial.println("From: " + imapData.getFrom(i));
|
||||||
|
Serial.println("From Charset: " + imapData.getFromCharset(i));
|
||||||
|
Serial.println("To: " + imapData.getTo(i));
|
||||||
|
Serial.println("To Charset: " + imapData.getToCharset(i));
|
||||||
|
Serial.println("CC: " + imapData.getCC(i));
|
||||||
|
Serial.println("CC Charset: " + imapData.getCCCharset(i));
|
||||||
|
Serial.println("Date: " + imapData.getDate(i));
|
||||||
|
Serial.println("Subject: " + imapData.getSubject(i));
|
||||||
|
Serial.println("Subject Charset: " + imapData.getSubjectCharset(i));
|
||||||
|
|
||||||
|
//If setHeaderOnly to false;
|
||||||
|
if (!imapData.isHeaderOnly())
|
||||||
|
{
|
||||||
|
Serial.println("Text Message: " + imapData.getTextMessage(i));
|
||||||
|
Serial.println("Text Message Charset: " + imapData.getTextMessgaeCharset(i));
|
||||||
|
Serial.println("HTML Message: " + imapData.getHTMLMessage(i));
|
||||||
|
Serial.println("HTML Message Charset: " + imapData.getHTMLMessgaeCharset(i));
|
||||||
|
if (imapData.isFetchMessageFailed(i))
|
||||||
|
Serial.println("Fetch Error: " + imapData.getFetchMessageFailedReason(i));
|
||||||
|
|
||||||
|
if (imapData.isDownloadMessageFailed(i))
|
||||||
|
Serial.println("Save Content Error: " + imapData.getDownloadMessageFailedReason(i));
|
||||||
|
|
||||||
|
if (imapData.getAttachmentCount(i) > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.println("**************");
|
||||||
|
Serial.println("Attachment: " + String(imapData.getAttachmentCount(i)) + " file(s)");
|
||||||
|
|
||||||
|
for (int j = 0; j < imapData.getAttachmentCount(i); j++)
|
||||||
|
{
|
||||||
|
Serial.println("File Index: " + String(j + 1));
|
||||||
|
Serial.println("Filename: " + imapData.getAttachmentFileName(i, j));
|
||||||
|
Serial.println("Name: " + imapData.getAttachmentName(i, j));
|
||||||
|
Serial.println("Size: " + String(imapData.getAttachmentFileSize(i, j)));
|
||||||
|
Serial.println("Type: " + imapData.getAttachmentType(i, j));
|
||||||
|
Serial.println("Creation Date: " + imapData.getAttachmentCreationDate(i, j));
|
||||||
|
if (imapData.isDownloadAttachmentFailed(i, j))
|
||||||
|
Serial.println("Download Attachment Error: " + imapData.getDownloadAttachmentFailedReason(i, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//List all files in SD card
|
||||||
|
void printDirectory(File &dir, int depth)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
File entry = dir.openNextFile();
|
||||||
|
if (!entry)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < depth; i++)
|
||||||
|
Serial.print("| ");
|
||||||
|
|
||||||
|
std::string name = entry.name();
|
||||||
|
if (entry.isDirectory())
|
||||||
|
{
|
||||||
|
Serial.print("+----" + String(name.substr(name.find_last_of("/\\") + 1).c_str()) + "\r\n");
|
||||||
|
printDirectory(entry, depth + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Serial.print("+--" + String(name.substr(name.find_last_of("/\\") + 1).c_str()));
|
||||||
|
Serial.print("\t\t\t(");
|
||||||
|
Serial.print(entry.size(), DEC);
|
||||||
|
Serial.println(")");
|
||||||
|
}
|
||||||
|
entry.close();
|
||||||
|
}
|
||||||
|
}
|
180
libesp32/ESP32-Mail-Client/examples/Send_email/Send_email.ino
Executable file
180
libesp32/ESP32-Mail-Client/examples/Send_email/Send_email.ino
Executable file
@ -0,0 +1,180 @@
|
|||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Created by K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
* Email: k_suwatchai@hotmail.com
|
||||||
|
*
|
||||||
|
* Github: https://github.com/mobizt
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 mobizt
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1
|
||||||
|
|
||||||
|
//To receive Email for Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en
|
||||||
|
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "ESP32_MailClient.h"
|
||||||
|
#include "SD.h"
|
||||||
|
|
||||||
|
//For demo only
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
|
#define WIFI_SSID "YOUR_WIFI_SSID"
|
||||||
|
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"
|
||||||
|
|
||||||
|
|
||||||
|
//The Email Sending data object contains config and data to send
|
||||||
|
SMTPData smtpData;
|
||||||
|
|
||||||
|
//Callback function to get the Email sending status
|
||||||
|
void sendCallback(SendStatus info);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("Connecting to AP");
|
||||||
|
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||||
|
while (WiFi.status() != WL_CONNECTED)
|
||||||
|
{
|
||||||
|
Serial.print(".");
|
||||||
|
delay(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("WiFi connected.");
|
||||||
|
Serial.println("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
|
||||||
|
Serial.println("Mounting SD Card...");
|
||||||
|
|
||||||
|
if (SD.begin()) // MailClient.sdBegin(14,2,15,13) for TTGO T8 v1.7 or 1.8
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.println("Preparing attach file...");
|
||||||
|
|
||||||
|
File file = SD.open("/text_file.txt", FILE_WRITE);
|
||||||
|
file.print("Hello World!\r\nHello World!");
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
file = SD.open("/binary_file.dat", FILE_WRITE);
|
||||||
|
|
||||||
|
static uint8_t buf[512];
|
||||||
|
|
||||||
|
buf[0] = 'H';
|
||||||
|
buf[1] = 'E';
|
||||||
|
buf[2] = 'A';
|
||||||
|
buf[3] = 'D';
|
||||||
|
file.write(buf, 4);
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
memset(buf, 0xff, 512);
|
||||||
|
for (i = 0; i < 2048; i++)
|
||||||
|
{
|
||||||
|
file.write(buf, 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = 'T';
|
||||||
|
buf[1] = 'A';
|
||||||
|
buf[2] = 'I';
|
||||||
|
buf[3] = 'L';
|
||||||
|
file.write(buf, 4);
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Serial.println("SD Card Monting Failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
|
||||||
|
Serial.println("Sending email...");
|
||||||
|
|
||||||
|
//Set the Email host, port, account and password
|
||||||
|
smtpData.setLogin("outlook.office365.com", 587, "YOUR_EMAIL_ACCOUNT@outlook.com", "YOUR_EMAIL_PASSWORD");
|
||||||
|
|
||||||
|
//For library version 1.2.0 and later which STARTTLS protocol was supported,the STARTTLS will be
|
||||||
|
//enabled automatically when port 587 was used, or enable it manually using setSTARTTLS function.
|
||||||
|
//smtpData.setSTARTTLS(true);
|
||||||
|
|
||||||
|
//Set the sender name and Email
|
||||||
|
smtpData.setSender("ESP32", "SOME_EMAIL_ACCOUNT@SOME_EMAIL.com");
|
||||||
|
|
||||||
|
//Set Email priority or importance High, Normal, Low or 1 to 5 (1 is highest)
|
||||||
|
smtpData.setPriority("High");
|
||||||
|
|
||||||
|
//Set the subject
|
||||||
|
smtpData.setSubject("ESP32 SMTP Mail Sending Test");
|
||||||
|
|
||||||
|
//Set the message - normal text or html format
|
||||||
|
smtpData.setMessage("<div style=\"color:#ff0000;font-size:20px;\">Hello World! - From ESP32</div>", true);
|
||||||
|
|
||||||
|
//Add recipients, can add more than one recipient
|
||||||
|
smtpData.addRecipient("SOME_RECIPIENT@SOME_MAIL.com");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Add attachments, can add the file or binary data from flash memory, file in SD card
|
||||||
|
//Data from internal memory
|
||||||
|
smtpData.addAttachData("firebase_logo.png", "image/png", (uint8_t *)dummyImageData, sizeof dummyImageData);
|
||||||
|
|
||||||
|
//Add attach files from SD card
|
||||||
|
//Comment these two lines, if no SD card connected
|
||||||
|
//Two files that previousely created.
|
||||||
|
smtpData.addAttachFile("/binary_file.dat");
|
||||||
|
smtpData.addAttachFile("/text_file.txt");
|
||||||
|
|
||||||
|
|
||||||
|
//Add some custom header to message
|
||||||
|
//See https://tools.ietf.org/html/rfc822
|
||||||
|
//These header fields can be read from raw or source of message when it received)
|
||||||
|
smtpData.addCustomMessageHeader("Date: Sat, 10 Aug 2019 21:39:56 -0700 (PDT)");
|
||||||
|
//Be careful when set Message-ID, it should be unique, otherwise message will not store
|
||||||
|
//smtpData.addCustomMessageHeader("Message-ID: <abcde.fghij@gmail.com>");
|
||||||
|
|
||||||
|
//Set the storage types to read the attach files (SD is default)
|
||||||
|
//smtpData.setFileStorageType(MailClientStorageType::SPIFFS);
|
||||||
|
smtpData.setFileStorageType(MailClientStorageType::SD);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
smtpData.setSendCallback(sendCallback);
|
||||||
|
|
||||||
|
//Start sending Email, can be set callback function to track the status
|
||||||
|
if (!MailClient.sendMail(smtpData))
|
||||||
|
Serial.println("Error sending Email, " + MailClient.smtpErrorReason());
|
||||||
|
|
||||||
|
//Clear all data from Email object to free memory
|
||||||
|
smtpData.empty();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//Callback function to get the Email sending status
|
||||||
|
void sendCallback(SendStatus msg)
|
||||||
|
{
|
||||||
|
//Print the current status
|
||||||
|
Serial.println(msg.info());
|
||||||
|
|
||||||
|
//Do something when complete
|
||||||
|
if (msg.success())
|
||||||
|
{
|
||||||
|
Serial.println("----------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1074
libesp32/ESP32-Mail-Client/examples/Send_email/image.h
Executable file
1074
libesp32/ESP32-Mail-Client/examples/Send_email/image.h
Executable file
File diff suppressed because it is too large
Load Diff
70
libesp32/ESP32-Mail-Client/examples/Set_flag/Set_flag.ino
Executable file
70
libesp32/ESP32-Mail-Client/examples/Set_flag/Set_flag.ino
Executable file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Created by K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
* Email: k_suwatchai@hotmail.com
|
||||||
|
*
|
||||||
|
* Github: https://github.com/mobizt
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 mobizt
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "ESP32_MailClient.h"
|
||||||
|
|
||||||
|
#define WIFI_SSID "YOUR_WIFI_SSID"
|
||||||
|
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"
|
||||||
|
|
||||||
|
//The Email Reading data object contains config and data that received
|
||||||
|
IMAPData imapData;
|
||||||
|
|
||||||
|
void readEmail();
|
||||||
|
|
||||||
|
unsigned long lastTime = 0;
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("Connecting to AP");
|
||||||
|
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||||
|
while (WiFi.status() != WL_CONNECTED)
|
||||||
|
{
|
||||||
|
Serial.print(".");
|
||||||
|
delay(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("WiFi connected.");
|
||||||
|
Serial.println("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
imapData.setLogin("imap.gmail.com", 993, "YOUR_EMAIL_ACCOUNT@gmail.com", "YOUR_EMAIL_PASSWORD");
|
||||||
|
imapData.setFolder("INBOX");
|
||||||
|
imapData.setDebug(true);
|
||||||
|
|
||||||
|
//Set \Seen and \Answered to flags for message with UID 100
|
||||||
|
MailClient.setFlag(imapData, 100, "\\Seen \\Answered");
|
||||||
|
|
||||||
|
//Add \Seen and \Answered to flags for message with UID 100
|
||||||
|
//MailClient.addFlag(imapData, 100, "\\Seen \\Answered");
|
||||||
|
|
||||||
|
//Remove \Seen and \Answered from flags for message with UID 100
|
||||||
|
//MailClient.removeFlag(imapData, 100, "\\Seen \\Answered");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
136
libesp32/ESP32-Mail-Client/examples/Time/Time.ino
Executable file
136
libesp32/ESP32-Mail-Client/examples/Time/Time.ino
Executable file
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* Created by K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
* Email: k_suwatchai@hotmail.com
|
||||||
|
*
|
||||||
|
* Github: https://github.com/mobizt
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 mobizt
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "ESP32_MailClient.h"
|
||||||
|
|
||||||
|
#define WIFI_SSID "YOUR_WIFI_SSID"
|
||||||
|
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("Connecting to AP");
|
||||||
|
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||||
|
while (WiFi.status() != WL_CONNECTED)
|
||||||
|
{
|
||||||
|
Serial.print(".");
|
||||||
|
delay(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("WiFi connected.");
|
||||||
|
Serial.println("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
//Set Clock
|
||||||
|
//GMT offset (3 Hrs), Daylight offset (0 Hrs)
|
||||||
|
MailClient.Time.setClock(3, 0);
|
||||||
|
|
||||||
|
Serial.println("Number of Days This Year (since January): " + String(MailClient.Time.getNumberOfDayThisYear()));
|
||||||
|
Serial.println("Day of Week Number: " + String(MailClient.Time.getDayOfWeek()));
|
||||||
|
Serial.println("Day of Week String: : " + String(MailClient.Time.getDayOfWeekString()));
|
||||||
|
Serial.println("Total seconds today: : " + String(MailClient.Time.getCurrentSecond()));
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!MailClient.Time.clockReady)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Print out current date and time
|
||||||
|
int d = MailClient.Time.getDay();
|
||||||
|
int m = MailClient.Time.getMonth();
|
||||||
|
int y = MailClient.Time.getYear();
|
||||||
|
int hr = MailClient.Time.getHour();
|
||||||
|
int min = MailClient.Time.getMin();
|
||||||
|
int sec = MailClient.Time.getSec();
|
||||||
|
Serial.print("Current Time (GMT+3): ");
|
||||||
|
Serial.print(d);
|
||||||
|
Serial.print("/");
|
||||||
|
Serial.print(m);
|
||||||
|
Serial.print("/");
|
||||||
|
Serial.print(y);
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(hr);
|
||||||
|
Serial.print(":");
|
||||||
|
Serial.print(min);
|
||||||
|
Serial.print(":");
|
||||||
|
Serial.println(sec);
|
||||||
|
|
||||||
|
uint32_t todayFromMidnightTimestamp = MailClient.Time.getTimestamp(y, m, d, 0, 0, 0);
|
||||||
|
uint32_t currentTimestamp = MailClient.Time.getUnixTime();
|
||||||
|
uint32_t totalSecondsFromMidnight = currentTimestamp - todayFromMidnightTimestamp;
|
||||||
|
|
||||||
|
//Assumed we countdown until 15:00:00 everyday
|
||||||
|
uint8_t targetSec = 0;
|
||||||
|
uint8_t targetMin = 0;
|
||||||
|
uint8_t targetHr = 15;
|
||||||
|
uint32_t targetSecondsFromMidnight = targetHr * 60 * 60 + targetMin * 60 + targetSec;
|
||||||
|
|
||||||
|
if (targetSecondsFromMidnight >= totalSecondsFromMidnight)
|
||||||
|
{
|
||||||
|
uint32_t diffSeconds = targetSecondsFromMidnight - totalSecondsFromMidnight;
|
||||||
|
int remainYrs, remainMonths, remainDays, remainHr, remainMin, remainSec;
|
||||||
|
MailClient.Time.getTimeFromSec(diffSeconds, remainYrs, remainMonths, remainDays, remainHr, remainMin, remainSec);
|
||||||
|
Serial.print("Everyday countdown until 15:00:00 is ");
|
||||||
|
Serial.print(remainHr);
|
||||||
|
Serial.print(" Hr, ");
|
||||||
|
Serial.print(remainMin);
|
||||||
|
Serial.print(" Min and ");
|
||||||
|
Serial.print(remainSec);
|
||||||
|
Serial.println(" Sec to go.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Serial.println("Everyday countdown until 15:00:00 was passed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Assumed we countdown until 18/12/2019 8:30:45
|
||||||
|
uint32_t targetTimestamp = MailClient.Time.getTimestamp(2019, 12, 18, 8, 30, 45);
|
||||||
|
if (targetTimestamp >= currentTimestamp)
|
||||||
|
{
|
||||||
|
uint32_t diffSeconds = targetTimestamp - currentTimestamp;
|
||||||
|
int remainYrs, remainMonths, remainDays, remainHr, remainMin, remainSec;
|
||||||
|
MailClient.Time.getTimeFromSec(diffSeconds, remainYrs, remainMonths, remainDays, remainHr, remainMin, remainSec);
|
||||||
|
Serial.print("One time countdown until 18/12/2019 8:30:45 is ");
|
||||||
|
Serial.print(remainYrs);
|
||||||
|
Serial.print(" Years, ");
|
||||||
|
Serial.print(remainMonths);
|
||||||
|
Serial.print(" Months, ");
|
||||||
|
Serial.print(remainDays);
|
||||||
|
Serial.print(" Days, ");
|
||||||
|
Serial.print(remainHr);
|
||||||
|
Serial.print(" Hr, ");
|
||||||
|
Serial.print(remainMin);
|
||||||
|
Serial.print(" Min and ");
|
||||||
|
Serial.print(remainSec);
|
||||||
|
Serial.println(" Sec to go.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Serial.println("One time countdown until 18/12/2019 8:30:45 was finished.");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
166
libesp32/ESP32-Mail-Client/keywords.txt
Executable file
166
libesp32/ESP32-Mail-Client/keywords.txt
Executable file
@ -0,0 +1,166 @@
|
|||||||
|
#######################################
|
||||||
|
# Syntax Coloring Map ESP32-Mail-Client
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Classes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
IMAPData KEYWORD1
|
||||||
|
SMTPData KEYWORD1
|
||||||
|
attachmentData KEYWORD1
|
||||||
|
SendStatus KEYWORD1
|
||||||
|
messageBodyData KEYWORD1
|
||||||
|
DownloadProgress KEYWORD1
|
||||||
|
MessageData KEYWORD1
|
||||||
|
|
||||||
|
TIME KEYWORD1
|
||||||
|
|
||||||
|
|
||||||
|
##################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
##################################
|
||||||
|
|
||||||
|
sendMail KEYWORD2
|
||||||
|
readMail KEYWORD2
|
||||||
|
smtpErrorReason KEYWORD2
|
||||||
|
imapErrorReason KEYWORD2
|
||||||
|
sdBegin KEYWORD2
|
||||||
|
setFlag KEYWORD2
|
||||||
|
addFlag KEYWORD2
|
||||||
|
removeFlag KEYWORD2
|
||||||
|
|
||||||
|
|
||||||
|
setClock KEYWORD2
|
||||||
|
getUnixTime KEYWORD2
|
||||||
|
getTimestamp KEYWORD2
|
||||||
|
getYear KEYWORD2
|
||||||
|
getMonth KEYWORD2
|
||||||
|
getDay KEYWORD2
|
||||||
|
getDayOfWeek KEYWORD2
|
||||||
|
getDayOfWeekString KEYWORD2
|
||||||
|
getHour KEYWORD2
|
||||||
|
getMin KEYWORD2
|
||||||
|
getSec KEYWORD2
|
||||||
|
getNumberOfDayThisYear KEYWORD2
|
||||||
|
getTotalDays KEYWORD2
|
||||||
|
dayofweek KEYWORD2
|
||||||
|
getCurrentSecond KEYWORD2
|
||||||
|
getCurrentTimestamp KEYWORD2
|
||||||
|
getTimeFromSec KEYWORD2
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# Methods for IMAP Data object (KEYWORD2)
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
setLogin KEYWORD2
|
||||||
|
setSTARTTLS KEYWORD2
|
||||||
|
setDebug KEYWORD2
|
||||||
|
setFolder KEYWORD2
|
||||||
|
setMessageBufferSize KEYWORD2
|
||||||
|
setAttachmentSizeLimit KEYWORD2
|
||||||
|
setSearchCriteria KEYWORD2
|
||||||
|
setSaveFilePath KEYWORD2
|
||||||
|
setFechUID KEYWORD2
|
||||||
|
setDownloadAttachment KEYWORD2
|
||||||
|
setHTMLMessage KEYWORD2
|
||||||
|
setTextMessage KEYWORD2
|
||||||
|
setSearchLimit KEYWORD2
|
||||||
|
setRecentSort KEYWORD2
|
||||||
|
setReadCallback KEYWORD2
|
||||||
|
setDownloadReport KEYWORD2
|
||||||
|
isHeaderOnly KEYWORD2
|
||||||
|
getFrom KEYWORD2
|
||||||
|
getFromCharset KEYWORD2
|
||||||
|
getTo KEYWORD2
|
||||||
|
getToCharset KEYWORD2
|
||||||
|
getCC KEYWORD2
|
||||||
|
getCCCharset KEYWORD2
|
||||||
|
getSubject KEYWORD2
|
||||||
|
getSubjectCharset KEYWORD2
|
||||||
|
getHTMLMessage KEYWORD2
|
||||||
|
getTextMessage KEYWORD2
|
||||||
|
getHTMLMessgaeCharset KEYWORD2
|
||||||
|
getTextMessgaeCharset KEYWORD2
|
||||||
|
getDate KEYWORD2
|
||||||
|
getUID KEYWORD2
|
||||||
|
getNumber KEYWORD2
|
||||||
|
getMessageID KEYWORD2
|
||||||
|
getAcceptLanguage KEYWORD2
|
||||||
|
getContentLanguage KEYWORD2
|
||||||
|
isFetchMessageFailed KEYWORD2
|
||||||
|
getFetchMessageFailedReason KEYWORD2
|
||||||
|
isDownloadAttachmentFailed KEYWORD2
|
||||||
|
getDownloadAttachmentFailedReason KEYWORD2
|
||||||
|
isDownloadMessageFailed KEYWORD2
|
||||||
|
getDownloadMessageFailedReason KEYWORD2
|
||||||
|
saveHTMLMessage KEYWORD2
|
||||||
|
saveTextMessage KEYWORD2
|
||||||
|
getFolderCount KEYWORD2
|
||||||
|
getFolder KEYWORD2
|
||||||
|
getFlagCount KEYWORD2
|
||||||
|
getFlag KEYWORD2
|
||||||
|
totalMessages KEYWORD2
|
||||||
|
searchCount KEYWORD2
|
||||||
|
availableMessages KEYWORD2
|
||||||
|
getAttachmentCount KEYWORD2
|
||||||
|
getAttachmentFileName KEYWORD2
|
||||||
|
getAttachmentName KEYWORD2
|
||||||
|
getAttachmentFileSize KEYWORD2
|
||||||
|
getAttachmentCreationDate KEYWORD2
|
||||||
|
getAttachmentType KEYWORD2
|
||||||
|
empty KEYWORD2
|
||||||
|
clearMessageData KEYWORD2
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# Methods for SMTP Data object (KEYWORD2)
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
setSender KEYWORD2
|
||||||
|
getFromName KEYWORD2
|
||||||
|
getSenderEmail KEYWORD2
|
||||||
|
setPriority KEYWORD2
|
||||||
|
getPriority KEYWORD2
|
||||||
|
addRecipient KEYWORD2
|
||||||
|
removeRecipient KEYWORD2
|
||||||
|
clearRecipient KEYWORD2
|
||||||
|
getRecipient KEYWORD2
|
||||||
|
recipientCount KEYWORD2
|
||||||
|
setSubject KEYWORD2
|
||||||
|
getSubject KEYWORD2
|
||||||
|
setMessage KEYWORD2
|
||||||
|
getMessage KEYWORD2
|
||||||
|
htmlFormat KEYWORD2
|
||||||
|
addCC KEYWORD2
|
||||||
|
removeCC KEYWORD2
|
||||||
|
clearCC KEYWORD2
|
||||||
|
getCC KEYWORD2
|
||||||
|
ccCount KEYWORD2
|
||||||
|
addBCC KEYWORD2
|
||||||
|
removeBCC KEYWORD2
|
||||||
|
clearBCC KEYWORD2
|
||||||
|
getBCC KEYWORD2
|
||||||
|
bccCount KEYWORD2
|
||||||
|
addAttachData KEYWORD2
|
||||||
|
removeAttachData KEYWORD2
|
||||||
|
attachDataCount KEYWORD2
|
||||||
|
addAttachFile KEYWORD2
|
||||||
|
removeAttachFile KEYWORD2
|
||||||
|
clearAttachData KEYWORD2
|
||||||
|
clearAttachFile KEYWORD2
|
||||||
|
clearAttachment KEYWORD2
|
||||||
|
attachFileCount KEYWORD2
|
||||||
|
setSendCallback KEYWORD2
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# Functions for ReadStatus and SendStatus classes (KEYWORD2)
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
SendStatus KEYWORD2
|
||||||
|
info KEYWORD2
|
||||||
|
success KEYWORD2
|
||||||
|
ReadStatus KEYWORD2
|
||||||
|
status KEYWORD2
|
||||||
|
|
||||||
|
clockReady KEYWORD3
|
17
libesp32/ESP32-Mail-Client/library.properties
Executable file
17
libesp32/ESP32-Mail-Client/library.properties
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
name=ESP32 Mail Client
|
||||||
|
|
||||||
|
version=2.1.4
|
||||||
|
|
||||||
|
author=Mobizt
|
||||||
|
|
||||||
|
maintainer=Mobizt <k_suwatchai@hotmail.com.com>
|
||||||
|
|
||||||
|
sentence=Mail Client Arduino Library for ESP32
|
||||||
|
|
||||||
|
paragraph=This library allows ESP32 to send Email with/without attachment and receive Email with/without attachment download through SMTP and IMAP servers.
|
||||||
|
|
||||||
|
category=Communication
|
||||||
|
|
||||||
|
url=https://github.com/mobizt/ESP32-Mail-Client
|
||||||
|
|
||||||
|
architectures=esp32
|
BIN
libesp32/ESP32-Mail-Client/media/images/esp32-mail.jpg
Executable file
BIN
libesp32/ESP32-Mail-Client/media/images/esp32-mail.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
libesp32/ESP32-Mail-Client/media/images/esp32-mail.png
Executable file
BIN
libesp32/ESP32-Mail-Client/media/images/esp32-mail.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
200
libesp32/ESP32-Mail-Client/src/ESP32MailHTTPClient.cpp
Executable file
200
libesp32/ESP32-Mail-Client/src/ESP32MailHTTPClient.cpp
Executable file
@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
* Customized version of ESP32 HTTPClient Library.
|
||||||
|
* Allow custom header and payload with STARTTLS support
|
||||||
|
*
|
||||||
|
* v 1.0.0
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
* Copyright (c) 2019 K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
* HTTPClient Arduino library for ESP32
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||||
|
* This file is part of the HTTPClient for Arduino.
|
||||||
|
* Port to ESP32 by Evandro Luis Copercini (2017),
|
||||||
|
* changed fingerprints to CA verification.
|
||||||
|
*
|
||||||
|
* 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 ESP32MailHTTPClient_CPP
|
||||||
|
#define ESP32MailHTTPClient_CPP
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
#include "ESP32MailHTTPClient.h"
|
||||||
|
|
||||||
|
class TransportTraits
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~TransportTraits() {}
|
||||||
|
|
||||||
|
virtual std::unique_ptr<WiFiClient> create()
|
||||||
|
{
|
||||||
|
return std::unique_ptr<WiFiClient>(new WiFiClient());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
verify(WiFiClient &client, const char *host, bool starttls, DebugMsgCallback cb)
|
||||||
|
{
|
||||||
|
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<WiFiClient> create() override
|
||||||
|
{
|
||||||
|
return std::unique_ptr<WiFiClient>(new WiFiClientSecureESP32());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool verify(WiFiClient &client, const char *host, bool starttls, DebugMsgCallback cb) override
|
||||||
|
{
|
||||||
|
WiFiClientSecureESP32 &wcs = static_cast<WiFiClientSecureESP32 &>(client);
|
||||||
|
wcs.setCACert(_cacert);
|
||||||
|
wcs.setCertificate(_clicert);
|
||||||
|
wcs.setPrivateKey(_clikey);
|
||||||
|
wcs.setSTARTTLS(starttls);
|
||||||
|
wcs.setDebugCB(cb);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char *_cacert;
|
||||||
|
const char *_clicert;
|
||||||
|
const char *_clikey;
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP32MailHTTPClient::ESP32MailHTTPClient() {}
|
||||||
|
|
||||||
|
ESP32MailHTTPClient::~ESP32MailHTTPClient()
|
||||||
|
{
|
||||||
|
if (_client)
|
||||||
|
_client->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESP32MailHTTPClient::begin(const char *host, uint16_t port, const char *uri, const char *CAcert)
|
||||||
|
{
|
||||||
|
transportTraits.reset(nullptr);
|
||||||
|
|
||||||
|
_host = host;
|
||||||
|
_port = port;
|
||||||
|
_uri = uri;
|
||||||
|
transportTraits = TransportTraitsPtr(new TLSTraits(CAcert));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESP32MailHTTPClient::connected()
|
||||||
|
{
|
||||||
|
if (_client)
|
||||||
|
return ((_client->available() > 0) || _client->connected());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESP32MailHTTPClient::sendHeader(const char *header)
|
||||||
|
{
|
||||||
|
if (!connected())
|
||||||
|
return false;
|
||||||
|
return (_client->write(header, strlen(header)) == strlen(header));
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32MailHTTPClient::sendRequest(const char *header, const char *payload)
|
||||||
|
{
|
||||||
|
size_t size = strlen(payload);
|
||||||
|
if (strlen(header) > 0)
|
||||||
|
{
|
||||||
|
if (!connect())
|
||||||
|
return HTTPC_ERROR_CONNECTION_REFUSED;
|
||||||
|
if (!sendHeader(header))
|
||||||
|
return HTTPC_ERROR_SEND_HEADER_FAILED;
|
||||||
|
}
|
||||||
|
if (size > 0)
|
||||||
|
if (_client->write(&payload[0], size) != size)
|
||||||
|
return HTTPC_ERROR_SEND_PAYLOAD_FAILED;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiClient *ESP32MailHTTPClient::getStreamPtr(void)
|
||||||
|
{
|
||||||
|
if (connected())
|
||||||
|
return _client.get();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESP32MailHTTPClient::connect(void)
|
||||||
|
{
|
||||||
|
if (connected())
|
||||||
|
{
|
||||||
|
while (_client->available() > 0)
|
||||||
|
_client->read();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!transportTraits)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_client = transportTraits->create();
|
||||||
|
|
||||||
|
if (!transportTraits->verify(*_client, _host.c_str(), false, _debugCallback))
|
||||||
|
{
|
||||||
|
_client->stop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_client->connect(_host.c_str(), _port))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESP32MailHTTPClient::connect(bool starttls)
|
||||||
|
{
|
||||||
|
if (connected())
|
||||||
|
{
|
||||||
|
while (_client->available() > 0)
|
||||||
|
_client->read();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!transportTraits)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_client = transportTraits->create();
|
||||||
|
|
||||||
|
if (!transportTraits->verify(*_client, _host.c_str(), starttls, _debugCallback))
|
||||||
|
{
|
||||||
|
_client->stop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_client->connect(_host.c_str(), _port))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32MailHTTPClient::setDebugCallback(DebugMsgCallback cb)
|
||||||
|
{
|
||||||
|
_debugCallback = std::move(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //ESP32
|
||||||
|
|
||||||
|
#endif //ESP32MailHTTPClient_CPP
|
107
libesp32/ESP32-Mail-Client/src/ESP32MailHTTPClient.h
Executable file
107
libesp32/ESP32-Mail-Client/src/ESP32MailHTTPClient.h
Executable file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Customized version of ESP32 HTTPClient Library.
|
||||||
|
* Allow custom header and payload with STARTTLS support
|
||||||
|
*
|
||||||
|
* v 1.0.0
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
* Copyright (c) 2019 K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
* HTTPClient Arduino library for ESP32
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||||
|
* This file is part of the HTTPClient for Arduino.
|
||||||
|
* Port to ESP32 by Evandro Luis Copercini (2017),
|
||||||
|
* changed fingerprints to CA verification.
|
||||||
|
*
|
||||||
|
* 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 ESP32MailHTTPClient_H
|
||||||
|
#define ESP32MailHTTPClient_H
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <HTTPClient.h>
|
||||||
|
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
#include "WiFiClientSecureESP32.h"
|
||||||
|
|
||||||
|
class ESP32MailHTTPClient : public HTTPClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ESP32MailHTTPClient();
|
||||||
|
~ESP32MailHTTPClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization of new http connection.
|
||||||
|
* \param host - Host name without protocols.
|
||||||
|
* \param port - Server's port.
|
||||||
|
* \param uri - The URI of resource.
|
||||||
|
* \param CAcert - The Base64 encode root certificate string
|
||||||
|
* \return True as default.
|
||||||
|
* If no certificate string provided, use (const char*)NULL to CAcert param
|
||||||
|
*/
|
||||||
|
bool begin(const char *host, uint16_t port, const char *uri, const char *CAcert);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the http connection status.
|
||||||
|
* \return True if connected.
|
||||||
|
*/
|
||||||
|
bool connected();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Establish http connection if header provided and send it, send payload if provided.
|
||||||
|
* \param header - The header string (constant chars array).
|
||||||
|
* \param payload - The payload string (constant chars array), optional.
|
||||||
|
* \return http status code, Return zero if new http connection and header and/or payload sent
|
||||||
|
* with no error or no header and payload provided. If obly payload provided, no new http connection was established.
|
||||||
|
*/
|
||||||
|
int sendRequest(const char *header, const char *payload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send extra header without making new http connection (if sendRequest has been called)
|
||||||
|
* \param header - The header string (constant chars array).
|
||||||
|
* \return True if header sending success.
|
||||||
|
* Need to call sendRequest with header first.
|
||||||
|
*/
|
||||||
|
bool sendHeader(const char *header);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the WiFi client pointer.
|
||||||
|
* \return WiFi client pointer.
|
||||||
|
*/
|
||||||
|
WiFiClient *getStreamPtr(void);
|
||||||
|
|
||||||
|
uint16_t tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT;
|
||||||
|
bool connect(void);
|
||||||
|
bool connect(bool starttls);
|
||||||
|
void setDebugCallback(DebugMsgCallback cb);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TransportTraitsPtr transportTraits;
|
||||||
|
std::unique_ptr<WiFiClient> _client;
|
||||||
|
DebugMsgCallback _debugCallback = NULL;
|
||||||
|
|
||||||
|
std::string _host = "";
|
||||||
|
std::string _uri = "";
|
||||||
|
uint16_t _port = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //ESP32
|
||||||
|
|
||||||
|
#endif //ESP32MailHTTPClient_H
|
191
libesp32/ESP32-Mail-Client/src/ESP32TimeHelper.cpp
Executable file
191
libesp32/ESP32-Mail-Client/src/ESP32TimeHelper.cpp
Executable file
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* ESP32 Internet Time Helper Arduino Library v 1.0.1
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
* Copyright (c) 2019 K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person returning a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ESP32TimeHelper_CPP
|
||||||
|
#define ESP32TimeHelper_CPP
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
#include "ESP32TimeHelper.h"
|
||||||
|
|
||||||
|
ESP32TimeHelper::ESP32TimeHelper()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
uint32_t ESP32TimeHelper::getUnixTime()
|
||||||
|
{
|
||||||
|
uint32_t utime = (msec_time_diff + millis()) / 1000;
|
||||||
|
return utime;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t ESP32TimeHelper::getTimestamp(int year, int mon, int date, int hour, int mins, int sec)
|
||||||
|
{
|
||||||
|
struct tm timeinfo;
|
||||||
|
timeinfo.tm_year = year - 1900;
|
||||||
|
timeinfo.tm_mon = mon - 1;
|
||||||
|
timeinfo.tm_mday = date;
|
||||||
|
timeinfo.tm_hour = hour;
|
||||||
|
timeinfo.tm_min = mins;
|
||||||
|
timeinfo.tm_sec = sec;
|
||||||
|
time_t ts = mktime(&timeinfo);
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESP32TimeHelper::setClock(float gmtOffset, float daylightOffset)
|
||||||
|
{
|
||||||
|
TZ = gmtOffset;
|
||||||
|
DST_MN = daylightOffset;
|
||||||
|
configTime((TZ)*3600, (DST_MN)*60, "pool.ntp.org", "time.nist.gov", NULL);
|
||||||
|
|
||||||
|
now = time(nullptr);
|
||||||
|
int cnt = 0;
|
||||||
|
while (now < 8 * 3600 * 2 && cnt < 20)
|
||||||
|
{
|
||||||
|
delay(50);
|
||||||
|
now = time(nullptr);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t tmp = now;
|
||||||
|
tmp = tmp * 1000;
|
||||||
|
msec_time_diff = tmp - millis();
|
||||||
|
|
||||||
|
getLocalTime(&timeinfo);
|
||||||
|
|
||||||
|
clockReady = now > 8 * 3600 * 2;
|
||||||
|
return clockReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32TimeHelper::getYear()
|
||||||
|
{
|
||||||
|
getLocalTime(&timeinfo);
|
||||||
|
return timeinfo.tm_year + 1900;
|
||||||
|
}
|
||||||
|
int ESP32TimeHelper::getMonth()
|
||||||
|
{
|
||||||
|
getLocalTime(&timeinfo);
|
||||||
|
return timeinfo.tm_mon + 1;
|
||||||
|
}
|
||||||
|
int ESP32TimeHelper::getDay()
|
||||||
|
{
|
||||||
|
getLocalTime(&timeinfo);
|
||||||
|
return timeinfo.tm_mday;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32TimeHelper::getDayOfWeek()
|
||||||
|
{
|
||||||
|
getLocalTime(&timeinfo);
|
||||||
|
return timeinfo.tm_wday;
|
||||||
|
}
|
||||||
|
String ESP32TimeHelper::getDayOfWeekString()
|
||||||
|
{
|
||||||
|
getLocalTime(&timeinfo);
|
||||||
|
return dow[timeinfo.tm_wday];
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32TimeHelper::getHour()
|
||||||
|
{
|
||||||
|
getLocalTime(&timeinfo);
|
||||||
|
return timeinfo.tm_hour;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32TimeHelper::getMin()
|
||||||
|
{
|
||||||
|
getLocalTime(&timeinfo);
|
||||||
|
return timeinfo.tm_min;
|
||||||
|
}
|
||||||
|
int ESP32TimeHelper::getSec()
|
||||||
|
{
|
||||||
|
getLocalTime(&timeinfo);
|
||||||
|
return timeinfo.tm_sec;
|
||||||
|
}
|
||||||
|
int ESP32TimeHelper::getNumberOfDayThisYear()
|
||||||
|
{
|
||||||
|
getLocalTime(&timeinfo);
|
||||||
|
return timeinfo.tm_yday + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32TimeHelper::totalDays(int y, int m, int d)
|
||||||
|
{
|
||||||
|
static char daytab[2][13] =
|
||||||
|
{
|
||||||
|
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||||
|
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
||||||
|
int daystotal = d;
|
||||||
|
for (int year = 1; year <= y; year++)
|
||||||
|
{
|
||||||
|
int max_month = (year < y ? 12 : m - 1);
|
||||||
|
int leap = (year % 4 == 0);
|
||||||
|
if (year % 100 == 0 && year % 400 != 0)
|
||||||
|
leap = 0;
|
||||||
|
for (int month = 1; month <= max_month; month++)
|
||||||
|
{
|
||||||
|
daystotal += daytab[leap][month];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return daystotal;
|
||||||
|
}
|
||||||
|
int ESP32TimeHelper::getTotalDays(int year, int month, int day)
|
||||||
|
{
|
||||||
|
return totalDays(year, month, day) - totalDays(1970, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32TimeHelper::dayofWeek(int year, int month, int day) /* 1 <= m <= 12, y > 1752 (in the U.K.) */
|
||||||
|
{
|
||||||
|
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
|
||||||
|
year -= month < 3;
|
||||||
|
return (year + year / 4 - year / 100 + year / 400 + t[month - 1] + day) % 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32TimeHelper::getCurrentSecond()
|
||||||
|
{
|
||||||
|
return (timeinfo.tm_hour * 3600) + (timeinfo.tm_min * 60) + timeinfo.tm_sec;
|
||||||
|
}
|
||||||
|
uint64_t ESP32TimeHelper::getCurrentTimestamp()
|
||||||
|
{
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
void ESP32TimeHelper::getTimeFromSec(int secCount, int &yrs, int &months, int &days, int &hr, int &min, int &sec)
|
||||||
|
{
|
||||||
|
int _yrs = secCount / (365 * 24 * 3600);
|
||||||
|
secCount = secCount - _yrs * (365 * 24 * 3600);
|
||||||
|
yrs = _yrs;
|
||||||
|
int _months = secCount / (30* 24 * 3600);
|
||||||
|
secCount = secCount - _months * (30 * 24 * 3600);
|
||||||
|
months = _months;
|
||||||
|
int _days = secCount / (24 * 3600);
|
||||||
|
secCount = secCount - _days * (24 * 3600);
|
||||||
|
days = _days;
|
||||||
|
int _hr = secCount / 3600;
|
||||||
|
secCount = secCount - _hr * 3600;
|
||||||
|
hr = _hr;
|
||||||
|
int _min = secCount / 60;
|
||||||
|
secCount = secCount - _min * 60;
|
||||||
|
min = _min;
|
||||||
|
sec = secCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //ESP32
|
||||||
|
|
||||||
|
#endif //ESP32TimeHelper_CPP
|
73
libesp32/ESP32-Mail-Client/src/ESP32TimeHelper.h
Executable file
73
libesp32/ESP32-Mail-Client/src/ESP32TimeHelper.h
Executable file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* ESP32 Internet Time Helper Arduino Library v 1.0.1
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
* Copyright (c) 2019 K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person returning a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ESP32TimeHelper_H
|
||||||
|
#define ESP32TimeHelper_H
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
|
||||||
|
class ESP32TimeHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ESP32TimeHelper();
|
||||||
|
bool clockReady = false;
|
||||||
|
bool setClock(float gmtOffset, float daylightOffset);
|
||||||
|
uint32_t getUnixTime();
|
||||||
|
time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec);
|
||||||
|
int getYear();
|
||||||
|
int getMonth();
|
||||||
|
int getDay();
|
||||||
|
int getDayOfWeek();
|
||||||
|
String getDayOfWeekString();
|
||||||
|
int getHour();
|
||||||
|
int getMin();
|
||||||
|
int getSec();
|
||||||
|
int getNumberOfDayThisYear();
|
||||||
|
int getTotalDays(int year, int month, int day);
|
||||||
|
int dayofWeek(int year, int month, int day);
|
||||||
|
int getCurrentSecond();
|
||||||
|
uint64_t getCurrentTimestamp();
|
||||||
|
void getTimeFromSec(int secCount, int &yrs, int &months, int &days, int &hr, int &min, int &sec);
|
||||||
|
|
||||||
|
private:
|
||||||
|
time_t now;
|
||||||
|
uint64_t msec_time_diff = 0;
|
||||||
|
struct tm timeinfo;
|
||||||
|
float TZ = 0.0;
|
||||||
|
float DST_MN = 0.0;
|
||||||
|
|
||||||
|
bool setClock();
|
||||||
|
int totalDays(int y, int m, int d);
|
||||||
|
const char *dow[20] = {"sunday", "monday", "tuesday", "wednesday", "thurseday", "friday", "saturday"};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //ESP32
|
||||||
|
|
||||||
|
#endif //ESP32TimeHelper_H
|
4875
libesp32/ESP32-Mail-Client/src/ESP32_MailClient.cpp
Executable file
4875
libesp32/ESP32-Mail-Client/src/ESP32_MailClient.cpp
Executable file
File diff suppressed because it is too large
Load Diff
1908
libesp32/ESP32-Mail-Client/src/ESP32_MailClient.h
Executable file
1908
libesp32/ESP32-Mail-Client/src/ESP32_MailClient.h
Executable file
File diff suppressed because it is too large
Load Diff
240
libesp32/ESP32-Mail-Client/src/RFC2047.cpp
Executable file
240
libesp32/ESP32-Mail-Client/src/RFC2047.cpp
Executable file
@ -0,0 +1,240 @@
|
|||||||
|
#ifndef RFC2047_CPP
|
||||||
|
#define RFC2047_CPP
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
#include "RFC2047.h"
|
||||||
|
|
||||||
|
RFC2047::RFC2047(){}
|
||||||
|
|
||||||
|
|
||||||
|
void RFC2047::rfc2047Decode(char *d, const char *s, size_t dlen){
|
||||||
|
|
||||||
|
const char *p, *q;
|
||||||
|
size_t n;
|
||||||
|
int found_encoded = 0;
|
||||||
|
|
||||||
|
dlen--; /* save room for the terminal nul */
|
||||||
|
|
||||||
|
while (*s && dlen > 0)
|
||||||
|
{
|
||||||
|
if ((p = strstr (s, "=?")) == NULL ||
|
||||||
|
(q = strchr (p + 2, '?')) == NULL ||
|
||||||
|
(q = strchr (q + 1, '?')) == NULL ||
|
||||||
|
(q = strstr (q + 1, "?=")) == NULL)
|
||||||
|
{
|
||||||
|
/* no encoded words */
|
||||||
|
if (d != s)
|
||||||
|
strfcpy (d, s, dlen + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p != s)
|
||||||
|
{
|
||||||
|
n = (size_t) (p - s);
|
||||||
|
/* ignore spaces between encoded words */
|
||||||
|
if (!found_encoded || strspn (s, " \t\r\n") != n)
|
||||||
|
{
|
||||||
|
if (n > dlen)
|
||||||
|
n = dlen;
|
||||||
|
if (d != s)
|
||||||
|
memcpy (d, s, n);
|
||||||
|
d += n;
|
||||||
|
dlen -= n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rfc2047DecodeWord (d, p, dlen);
|
||||||
|
found_encoded = 1;
|
||||||
|
s = q + 2;
|
||||||
|
n = strlen (d);
|
||||||
|
dlen -= n;
|
||||||
|
d += n;
|
||||||
|
}
|
||||||
|
*d = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void RFC2047::rfc2047DecodeWord(char *d, const char *s, size_t dlen){
|
||||||
|
|
||||||
|
char *p = safe_strdup (s);
|
||||||
|
char *pp = p;
|
||||||
|
char *pd = d;
|
||||||
|
size_t len = dlen;
|
||||||
|
int enc = 0, filter = 0, count = 0, c1, c2, c3, c4;
|
||||||
|
|
||||||
|
while ((pp = strtok (pp, "?")) != NULL)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
switch (count)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if (strcasecmp (pp, Charset) != 0)
|
||||||
|
{
|
||||||
|
filter = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (toupper (*pp) == 'Q')
|
||||||
|
enc = ENCQUOTEDPRINTABLE;
|
||||||
|
else if (toupper (*pp) == 'B')
|
||||||
|
enc = ENCBASE64;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (enc == ENCQUOTEDPRINTABLE)
|
||||||
|
{
|
||||||
|
while (*pp && len > 0)
|
||||||
|
{
|
||||||
|
if (*pp == '_')
|
||||||
|
{
|
||||||
|
*pd++ = ' ';
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
else if (*pp == '=')
|
||||||
|
{
|
||||||
|
*pd++ = (hexval(pp[1]) << 4) | hexval(pp[2]);
|
||||||
|
len--;
|
||||||
|
pp += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pd++ = *pp;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
pp++;
|
||||||
|
}
|
||||||
|
*pd = 0;
|
||||||
|
}
|
||||||
|
else if (enc == ENCBASE64)
|
||||||
|
{
|
||||||
|
while (*pp && len > 0)
|
||||||
|
{
|
||||||
|
c1 = base64val(pp[0]);
|
||||||
|
c2 = base64val(pp[1]);
|
||||||
|
*pd++ = (c1 << 2) | ((c2 >> 4) & 0x3);
|
||||||
|
if (--len == 0) break;
|
||||||
|
|
||||||
|
if (pp[2] == '=') break;
|
||||||
|
|
||||||
|
c3 = base64val(pp[2]);
|
||||||
|
*pd++ = ((c2 & 0xf) << 4) | ((c3 >> 2) & 0xf);
|
||||||
|
if (--len == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (pp[3] == '=')
|
||||||
|
break;
|
||||||
|
|
||||||
|
c4 = base64val(pp[3]);
|
||||||
|
*pd++ = ((c3 & 0x3) << 6) | c4;
|
||||||
|
if (--len == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pp += 4;
|
||||||
|
}
|
||||||
|
*pd = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pp = 0;
|
||||||
|
}
|
||||||
|
safe_free (&p);
|
||||||
|
if (filter)
|
||||||
|
{
|
||||||
|
|
||||||
|
pd = d;
|
||||||
|
while (*pd)
|
||||||
|
{
|
||||||
|
if (!IsPrint (*pd))
|
||||||
|
*pd = '?';
|
||||||
|
pd++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *RFC2047::safe_calloc (size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if (!nmemb || !size)
|
||||||
|
return NULL;
|
||||||
|
if (!(p = calloc (nmemb, size)))
|
||||||
|
{
|
||||||
|
//out of memory
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *RFC2047::safe_malloc (unsigned int siz)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if (siz == 0)
|
||||||
|
return 0;
|
||||||
|
if ((p = (void *) malloc (siz)) == 0)
|
||||||
|
{
|
||||||
|
//out of memory
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RFC2047::safe_realloc (void **p, size_t siz)
|
||||||
|
{
|
||||||
|
void *r;
|
||||||
|
|
||||||
|
if (siz == 0)
|
||||||
|
{
|
||||||
|
if (*p)
|
||||||
|
{
|
||||||
|
free (*p);
|
||||||
|
*p = NULL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p)
|
||||||
|
r = (void *) realloc (*p, siz);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = (void *) malloc (siz);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!r)
|
||||||
|
{
|
||||||
|
//out of memory
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RFC2047::safe_free (void *ptr)
|
||||||
|
{
|
||||||
|
void **p = (void **)ptr;
|
||||||
|
if (*p)
|
||||||
|
{
|
||||||
|
free (*p);
|
||||||
|
*p = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *RFC2047::safe_strdup (const char *s)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
size_t l;
|
||||||
|
|
||||||
|
if (!s || !*s) return 0;
|
||||||
|
l = strlen (s) + 1;
|
||||||
|
p = (char *)safe_malloc (l);
|
||||||
|
memcpy (p, s, l);
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //ESP32
|
||||||
|
|
||||||
|
#endif //RFC2047_CPP
|
70
libesp32/ESP32-Mail-Client/src/RFC2047.h
Executable file
70
libesp32/ESP32-Mail-Client/src/RFC2047.h
Executable file
@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
#ifndef RFC2047_H
|
||||||
|
#define RFC2047_H
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define strfcpy(A,B,C) strncpy(A,B,C), *(A+(C)-1)=0
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ENCOTHER,
|
||||||
|
ENC7BIT,
|
||||||
|
ENC8BIT,
|
||||||
|
ENCQUOTEDPRINTABLE,
|
||||||
|
ENCBASE64,
|
||||||
|
ENCBINARY
|
||||||
|
};
|
||||||
|
|
||||||
|
__attribute__((used)) static const char *Charset = "utf-8";
|
||||||
|
|
||||||
|
__attribute__((used)) static int Index_hex[128] = {
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||||
|
|
||||||
|
__attribute__((used)) static int Index_64[128] = {
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
||||||
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||||
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||||
|
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||||
|
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1};
|
||||||
|
|
||||||
|
#define IsPrint(c) (isprint((unsigned char)(c)) || \
|
||||||
|
((unsigned char)(c) >= 0xa0))
|
||||||
|
|
||||||
|
#define hexval(c) Index_hex[(unsigned int)(c)]
|
||||||
|
#define base64val(c) Index_64[(unsigned int)(c)]
|
||||||
|
|
||||||
|
class RFC2047{
|
||||||
|
|
||||||
|
public:
|
||||||
|
RFC2047();
|
||||||
|
void rfc2047Decode(char *d, const char *s, size_t dlen);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void rfc2047DecodeWord(char *d, const char *s, size_t dlen);
|
||||||
|
void *safe_calloc (size_t nmemb, size_t size);
|
||||||
|
void *safe_malloc (unsigned int siz);
|
||||||
|
void safe_realloc (void **p, size_t siz);
|
||||||
|
void safe_free (void *ptr);
|
||||||
|
char *safe_strdup (const char *s);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //ESP32
|
||||||
|
|
||||||
|
#endif //RFC2047_H
|
397
libesp32/ESP32-Mail-Client/src/WiFiClientSecureESP32.cpp
Executable file
397
libesp32/ESP32-Mail-Client/src/WiFiClientSecureESP32.cpp
Executable file
@ -0,0 +1,397 @@
|
|||||||
|
/*
|
||||||
|
*Customized WiFiClientSecure.cpp to support STARTTLS protocol, version 1.0.1
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
* Copyright (c) 2019 K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
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 WiFiClientSecureESP32_CPP
|
||||||
|
#define WiFiClientSecureESP32_CPP
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
#include "WiFiClientSecureESP32.h"
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
#include <lwip/netdb.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#undef connect
|
||||||
|
#undef write
|
||||||
|
#undef read
|
||||||
|
|
||||||
|
|
||||||
|
WiFiClientSecureESP32::WiFiClientSecureESP32()
|
||||||
|
{
|
||||||
|
_connected = false;
|
||||||
|
|
||||||
|
sslclient = new sslclient_context32;
|
||||||
|
ssl_init(sslclient);
|
||||||
|
sslclient->socket = -1;
|
||||||
|
sslclient->handshake_timeout = 120000;
|
||||||
|
_CA_cert = NULL;
|
||||||
|
_cert = NULL;
|
||||||
|
_private_key = NULL;
|
||||||
|
_pskIdent = NULL;
|
||||||
|
_psKey = NULL;
|
||||||
|
next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WiFiClientSecureESP32::WiFiClientSecureESP32(int sock)
|
||||||
|
{
|
||||||
|
_connected = false;
|
||||||
|
_timeout = 0;
|
||||||
|
|
||||||
|
sslclient = new sslclient_context32;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiClientSecureESP32::WiFiClientSecureESP32(bool starttls)
|
||||||
|
{
|
||||||
|
_connected = false;
|
||||||
|
|
||||||
|
sslclient = new sslclient_context32;
|
||||||
|
ssl_init(sslclient);
|
||||||
|
sslclient->socket = -1;
|
||||||
|
sslclient->handshake_timeout = 120000;
|
||||||
|
sslclient->starttls = true;
|
||||||
|
_CA_cert = NULL;
|
||||||
|
_cert = NULL;
|
||||||
|
_private_key = NULL;
|
||||||
|
_pskIdent = NULL;
|
||||||
|
_psKey = NULL;
|
||||||
|
next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiClientSecureESP32::~WiFiClientSecureESP32()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
delete sslclient;
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiClientSecureESP32 &WiFiClientSecureESP32::operator=(const WiFiClientSecureESP32 &other)
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
sslclient->socket = other.sslclient->socket;
|
||||||
|
_connected = other._connected;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiClientSecureESP32::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 WiFiClientSecureESP32::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 WiFiClientSecureESP32::connect(IPAddress ip, uint16_t port, int32_t timeout){
|
||||||
|
_timeout = timeout;
|
||||||
|
return connect(ip, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
int WiFiClientSecureESP32::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 WiFiClientSecureESP32::connect(const char *host, uint16_t port, int32_t timeout){
|
||||||
|
_timeout = timeout;
|
||||||
|
return connect(host, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
int WiFiClientSecureESP32::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 WiFiClientSecureESP32::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 WiFiClientSecureESP32::connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey) {
|
||||||
|
return connect(ip.toString().c_str(), port,_pskIdent, _psKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
int WiFiClientSecureESP32::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 WiFiClientSecureESP32::peek(){
|
||||||
|
if(_peek >= 0){
|
||||||
|
return _peek;
|
||||||
|
}
|
||||||
|
_peek = timedRead();
|
||||||
|
return _peek;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t WiFiClientSecureESP32::write(uint8_t data)
|
||||||
|
{
|
||||||
|
return write(&data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int WiFiClientSecureESP32::read()
|
||||||
|
{
|
||||||
|
uint8_t data = -1;
|
||||||
|
int res = read(&data, 1);
|
||||||
|
if (res < 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t WiFiClientSecureESP32::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 WiFiClientSecureESP32::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 WiFiClientSecureESP32::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 WiFiClientSecureESP32::connected()
|
||||||
|
{
|
||||||
|
uint8_t dummy = 0;
|
||||||
|
read(&dummy, 0);
|
||||||
|
|
||||||
|
return _connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiClientSecureESP32::setCACert (const char *rootCA)
|
||||||
|
{
|
||||||
|
_CA_cert = rootCA;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiClientSecureESP32::setCertificate (const char *client_ca)
|
||||||
|
{
|
||||||
|
_cert = client_ca;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiClientSecureESP32::setPrivateKey (const char *private_key)
|
||||||
|
{
|
||||||
|
_private_key = private_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiClientSecureESP32::setPreSharedKey(const char *pskIdent, const char *psKey) {
|
||||||
|
_pskIdent = pskIdent;
|
||||||
|
_psKey = psKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WiFiClientSecureESP32::verify(const char* fp, const char* domain_name)
|
||||||
|
{
|
||||||
|
if (!sslclient)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return verify_ssl_fingerprint(sslclient, fp, domain_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *WiFiClientSecureESP32::_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 WiFiClientSecureESP32::loadCACert(Stream& stream, size_t size) {
|
||||||
|
char *dest = _streamLoad(stream, size);
|
||||||
|
bool ret = false;
|
||||||
|
if (dest) {
|
||||||
|
setCACert(dest);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WiFiClientSecureESP32::loadCertificate(Stream& stream, size_t size) {
|
||||||
|
char *dest = _streamLoad(stream, size);
|
||||||
|
bool ret = false;
|
||||||
|
if (dest) {
|
||||||
|
setCertificate(dest);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WiFiClientSecureESP32::loadPrivateKey(Stream& stream, size_t size) {
|
||||||
|
char *dest = _streamLoad(stream, size);
|
||||||
|
bool ret = false;
|
||||||
|
if (dest) {
|
||||||
|
setPrivateKey(dest);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WiFiClientSecureESP32::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 WiFiClientSecureESP32::setHandshakeTimeout(unsigned long handshake_timeout)
|
||||||
|
{
|
||||||
|
sslclient->handshake_timeout = handshake_timeout * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiClientSecureESP32::setSTARTTLS(bool starttls)
|
||||||
|
{
|
||||||
|
sslclient->starttls = starttls;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiClientSecureESP32::setDebugCB(DebugMsgCallback cb)
|
||||||
|
{
|
||||||
|
sslclient->_debugCallback = std::move(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //ESP32
|
||||||
|
|
||||||
|
#endif //WiFiClientSecureESP32_CPP
|
145
libesp32/ESP32-Mail-Client/src/WiFiClientSecureESP32.h
Executable file
145
libesp32/ESP32-Mail-Client/src/WiFiClientSecureESP32.h
Executable file
@ -0,0 +1,145 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
*Customized WiFiClientSecure.h to support STARTTLS protocol, version 1.0.1
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
* Copyright (c) 2019 K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
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 WiFiClientSecureESP32_H
|
||||||
|
#define WiFiClientSecureESP32_H
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "IPAddress.h"
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include "ssl_client32.h"
|
||||||
|
|
||||||
|
typedef void (*DebugMsgCallback)(const char* msg);
|
||||||
|
|
||||||
|
class WiFiClientSecureESP32 : public WiFiClient
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
sslclient_context32 *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
|
||||||
|
DebugMsgCallback _debugCallback = NULL;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WiFiClientSecureESP32 *next;
|
||||||
|
WiFiClientSecureESP32();
|
||||||
|
WiFiClientSecureESP32(int socket);
|
||||||
|
WiFiClientSecureESP32(bool starttls);
|
||||||
|
~WiFiClientSecureESP32();
|
||||||
|
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);
|
||||||
|
void setSTARTTLS(bool starttls);
|
||||||
|
void setDebugCB(DebugMsgCallback cb);
|
||||||
|
|
||||||
|
operator bool()
|
||||||
|
{
|
||||||
|
return connected();
|
||||||
|
}
|
||||||
|
WiFiClientSecureESP32 &operator=(const WiFiClientSecureESP32 &other);
|
||||||
|
bool operator==(const bool value)
|
||||||
|
{
|
||||||
|
return bool() == value;
|
||||||
|
}
|
||||||
|
bool operator!=(const bool value)
|
||||||
|
{
|
||||||
|
return bool() != value;
|
||||||
|
}
|
||||||
|
bool operator==(const WiFiClientSecureESP32 &);
|
||||||
|
bool operator!=(const WiFiClientSecureESP32 &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
|
||||||
|
|
||||||
|
|
853
libesp32/ESP32-Mail-Client/src/ssl_client32.cpp
Executable file
853
libesp32/ESP32-Mail-Client/src/ssl_client32.cpp
Executable file
@ -0,0 +1,853 @@
|
|||||||
|
/*
|
||||||
|
*Customized ssl_client.cpp to support STARTTLS protocol, version 1.0.3
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
* Copyright (c) 2019 K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 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 SSL_CLIENT32_CPP
|
||||||
|
#define SSL_CLIENT32_CPP
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include <esp32-hal-log.h>
|
||||||
|
#include <lwip/err.h>
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
#include <lwip/sys.h>
|
||||||
|
#include <lwip/netdb.h>
|
||||||
|
#include <mbedtls/sha256.h>
|
||||||
|
#include <mbedtls/oid.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
#include "ssl_client32.h"
|
||||||
|
#include "WiFi.h"
|
||||||
|
|
||||||
|
const char *pers32 = "esp32-tls";
|
||||||
|
|
||||||
|
static int handle_error(int err)
|
||||||
|
{
|
||||||
|
if (err == -30848)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#ifdef MBEDTLS_ERROR_C
|
||||||
|
char error_buf[100];
|
||||||
|
mbedtls_strerror(err, error_buf, 100);
|
||||||
|
log_e("%s", error_buf);
|
||||||
|
#endif
|
||||||
|
log_e("MbedTLS message code: %d", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_init(sslclient_context32 *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);
|
||||||
|
mbedtls_net_init(&ssl_client->server_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int start_ssl_client(sslclient_context32 *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;
|
||||||
|
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_2, ssl_client);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_3, ssl_client);
|
||||||
|
log_e("ERROR opening socket");
|
||||||
|
return ssl_client->socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress srv((uint32_t)0);
|
||||||
|
if (!WiFiGenericClass::hostByName(host, srv))
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_4, ssl_client);
|
||||||
|
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 (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_5, ssl_client);
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_6, ssl_client);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_7, ssl_client);
|
||||||
|
log_e("Connect to Server failed!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fcntl(ssl_client->socket, F_SETFL, fcntl(ssl_client->socket, F_GETFL, 0) | O_NONBLOCK);
|
||||||
|
|
||||||
|
if (ssl_client->starttls && (port == 25 || port == 587 || port == 143))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_8, ssl_client);
|
||||||
|
|
||||||
|
if ((ret = starttlsHandshake(ssl_client, port)) != 0)
|
||||||
|
{
|
||||||
|
log_e("STARTTLS failed!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_9, ssl_client);
|
||||||
|
|
||||||
|
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 *)pers32, strlen(pers32));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
{
|
||||||
|
char *error_buf = new char[100];
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
strcpy_P(buf, ESP32_SSL_CLIENT_STR_1);
|
||||||
|
mbedtls_strerror(ret, error_buf, 100);
|
||||||
|
strcat(buf, error_buf);
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
delete[] error_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle_error(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_10, ssl_client);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
{
|
||||||
|
char *error_buf = new char[100];
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
strcpy_P(buf, ESP32_SSL_CLIENT_STR_1);
|
||||||
|
mbedtls_strerror(ret, error_buf, 100);
|
||||||
|
strcat(buf, error_buf);
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
delete[] error_buf;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_11, ssl_client);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
{
|
||||||
|
char *error_buf = new char[100];
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
strcpy_P(buf, ESP32_SSL_CLIENT_STR_1);
|
||||||
|
mbedtls_strerror(ret, error_buf, 100);
|
||||||
|
strcat(buf, error_buf);
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
delete[] error_buf;
|
||||||
|
}
|
||||||
|
return handle_error(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pskIdent != NULL && psKey != NULL)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_12, ssl_client);
|
||||||
|
log_v("Setting up PSK");
|
||||||
|
// convert PSK from hex to binary
|
||||||
|
if ((strlen(psKey) & 1) != 0 || strlen(psKey) > 2 * MBEDTLS_PSK_MAX_LEN)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_13, ssl_client);
|
||||||
|
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
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_14, ssl_client);
|
||||||
|
ret = mbedtls_ssl_conf_psk(&ssl_client->ssl_conf, psk, psk_len,
|
||||||
|
(const unsigned char *)pskIdent, strlen(pskIdent));
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
{
|
||||||
|
char *error_buf = new char[100];
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
strcpy_P(buf, ESP32_SSL_CLIENT_STR_1);
|
||||||
|
mbedtls_strerror(ret, error_buf, 100);
|
||||||
|
strcat(buf, error_buf);
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
delete[] error_buf;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_15, ssl_client);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
{
|
||||||
|
char *error_buf = new char[100];
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
strcpy_P(buf, ESP32_SSL_CLIENT_STR_1);
|
||||||
|
mbedtls_strerror(ret, error_buf, 100);
|
||||||
|
strcat(buf, error_buf);
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
delete[] error_buf;
|
||||||
|
}
|
||||||
|
return handle_error(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_16, ssl_client);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_17, ssl_client);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
{
|
||||||
|
char *error_buf = new char[100];
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
strcpy_P(buf, ESP32_SSL_CLIENT_STR_1);
|
||||||
|
mbedtls_strerror(ret, error_buf, 100);
|
||||||
|
strcat(buf, error_buf);
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
delete[] error_buf;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
{
|
||||||
|
char *error_buf = new char[100];
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
strcpy_P(buf, ESP32_SSL_CLIENT_STR_1);
|
||||||
|
mbedtls_strerror(ret, error_buf, 100);
|
||||||
|
strcat(buf, error_buf);
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
delete[] error_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle_error(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_ssl_set_bio(&ssl_client->ssl_ctx, &ssl_client->socket, mbedtls_net_send, mbedtls_net_recv, NULL);
|
||||||
|
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_18, ssl_client);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
{
|
||||||
|
char *error_buf = new char[100];
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
strcpy_P(buf, ESP32_SSL_CLIENT_STR_1);
|
||||||
|
mbedtls_strerror(ret, error_buf, 100);
|
||||||
|
strcat(buf, error_buf);
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
delete[] error_buf;
|
||||||
|
}
|
||||||
|
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)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_19, ssl_client);
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_20, ssl_client);
|
||||||
|
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
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_21, ssl_client);
|
||||||
|
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(sslclient_context32 *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_22, ssl_client);
|
||||||
|
log_v("Cleaning SSL connection.");
|
||||||
|
|
||||||
|
if (ssl_client->socket >= 0)
|
||||||
|
{
|
||||||
|
close(ssl_client->socket);
|
||||||
|
ssl_client->socket = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_ssl_free(&ssl_client->ssl_ctx);
|
||||||
|
mbedtls_ssl_config_free(&ssl_client->ssl_conf);
|
||||||
|
mbedtls_ctr_drbg_free(&ssl_client->drbg_ctx);
|
||||||
|
mbedtls_entropy_free(&ssl_client->entropy_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int data_to_read(sslclient_context32 *ssl_client)
|
||||||
|
{
|
||||||
|
int ret, res;
|
||||||
|
ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, NULL, 0);
|
||||||
|
//log_e("RET: %i",ret); //for low level debug
|
||||||
|
res = mbedtls_ssl_get_bytes_avail(&ssl_client->ssl_ctx);
|
||||||
|
//log_e("RES: %i",res); //for low level debug
|
||||||
|
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
{
|
||||||
|
char *buf = new char[512];
|
||||||
|
char *error_buf = new char[100];
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
strcpy_P(buf, ESP32_SSL_CLIENT_STR_1);
|
||||||
|
mbedtls_strerror(ret, error_buf, 100);
|
||||||
|
strcat(buf, error_buf);
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
delete[] error_buf;
|
||||||
|
delete[] buf;
|
||||||
|
}
|
||||||
|
return handle_error(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int send_ssl_data(sslclient_context32 *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(sslclient_context32 *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(sslclient_context32 *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)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_23, ssl_client);
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_24, ssl_client);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_25, ssl_client);
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_26, ssl_client);
|
||||||
|
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(sslclient_context32 *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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int starttlsHandshake(sslclient_context32 *ssl_client, int port)
|
||||||
|
{
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
size_t msgLen = 100;
|
||||||
|
size_t bufLen = 512;
|
||||||
|
char *buf = new char[bufLen];
|
||||||
|
char *hMsg = new char[msgLen];
|
||||||
|
|
||||||
|
fd_set readset;
|
||||||
|
fd_set writeset;
|
||||||
|
fd_set errset;
|
||||||
|
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
FD_ZERO(&readset);
|
||||||
|
FD_SET(ssl_client->socket, &readset);
|
||||||
|
FD_ZERO(&writeset);
|
||||||
|
FD_SET(ssl_client->socket, &writeset);
|
||||||
|
|
||||||
|
FD_ZERO(&errset);
|
||||||
|
FD_SET(ssl_client->socket, &errset);
|
||||||
|
|
||||||
|
tv.tv_sec = 1;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
ret = lwip_select(ssl_client->socket, &readset, &writeset, &errset, &tv);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_27, ssl_client);
|
||||||
|
|
||||||
|
goto starttls_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = read(ssl_client->socket, buf, bufLen);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_28, ssl_client);
|
||||||
|
goto starttls_exit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port == 587 || port == 25)
|
||||||
|
{
|
||||||
|
|
||||||
|
memset(hMsg, 0, msgLen);
|
||||||
|
strcpy_P(hMsg, ESP32_SSL_CLIENT_STR_29);
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_30, ssl_client);
|
||||||
|
ret = lwip_write(ssl_client->socket, hMsg, strlen(hMsg));
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_31, ssl_client);
|
||||||
|
goto starttls_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = lwip_select(ssl_client->socket, &readset, &writeset, &errset, &tv);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_32, ssl_client);
|
||||||
|
goto starttls_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, bufLen);
|
||||||
|
ret = lwip_read(ssl_client->socket, buf, bufLen);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_33, ssl_client);
|
||||||
|
goto starttls_exit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(hMsg, 0, msgLen);
|
||||||
|
strcpy_P(hMsg, ESP32_SSL_CLIENT_STR_34);
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_35, ssl_client);
|
||||||
|
ret = lwip_write(ssl_client->socket, hMsg, strlen(hMsg));
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_36, ssl_client);
|
||||||
|
goto starttls_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = lwip_select(ssl_client->socket, &readset, &writeset, &errset, &tv);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_37, ssl_client);
|
||||||
|
goto starttls_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, bufLen);
|
||||||
|
ret = lwip_read(ssl_client->socket, buf, bufLen);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_38, ssl_client);
|
||||||
|
goto starttls_exit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ssl_client->_debugCallback)
|
||||||
|
ssl_client->_debugCallback(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] buf;
|
||||||
|
delete[] hMsg;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
starttls_exit:
|
||||||
|
|
||||||
|
delete[] buf;
|
||||||
|
delete[] hMsg;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32SSLClientDebugInfo(PGM_P info, sslclient_context32 *ssl_client)
|
||||||
|
{
|
||||||
|
size_t dbgInfoLen = strlen_P(info) + 1;
|
||||||
|
char *dbgInfo = new char[dbgInfoLen];
|
||||||
|
memset(dbgInfo, 0, dbgInfoLen);
|
||||||
|
strcpy_P(dbgInfo, info);
|
||||||
|
ssl_client->_debugCallback(dbgInfo);
|
||||||
|
delete[] dbgInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //ESP32
|
||||||
|
|
||||||
|
#endif //SSL_CLIENT32_CPP
|
116
libesp32/ESP32-Mail-Client/src/ssl_client32.h
Executable file
116
libesp32/ESP32-Mail-Client/src/ssl_client32.h
Executable file
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
*Customized ssl_client.h to support STARTTLS protocol, version 1.0.3
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
* Copyright (c) 2019 K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Provide SSL/TLS functions to ESP32 with Arduino IDE
|
||||||
|
* by Evandro Copercini - 2017 - Apache 2.0 License
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SSL_CLIENT32_H
|
||||||
|
#define SSL_CLIENT32_H
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#include "mbedtls/net.h"
|
||||||
|
#include "mbedtls/debug.h"
|
||||||
|
#include "mbedtls/ssl.h"
|
||||||
|
#include "mbedtls/entropy.h"
|
||||||
|
#include "mbedtls/ctr_drbg.h"
|
||||||
|
#include "mbedtls/error.h"
|
||||||
|
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_1[] PROGMEM = "ERROR: ";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_2[] PROGMEM = "INFO: starting socket";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_3[] PROGMEM = "ERROR: opening socket";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_4[] PROGMEM = "ERROR: could not get ip from host";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_5[] PROGMEM = "INFO: connecting to Server...";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_6[] PROGMEM = "INFO: server connected";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_7[] PROGMEM = "ERROR: connect to Server failed!";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_8[] PROGMEM = "INFO: begin STARTTLS handshake";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_9[] PROGMEM = "INFO: seeding the random number generator";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_10[] PROGMEM = "INFO: setting up the SSL/TLS structure...";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_11[] PROGMEM = "INFO: loading CA cert";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_12[] PROGMEM = "INFO: setting up PSK";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_13[] PROGMEM = "ERROR: pre-shared key not valid hex or too long";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_14[] PROGMEM = "INFO: set mbedtls config";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_15[] PROGMEM = "INFO: loading CRT cert";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_16[] PROGMEM = "INFO: loading private key";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_17[] PROGMEM = "INFO: setting hostname for TLS session...";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_18[] PROGMEM = "INFO: performing the SSL/TLS handshake...";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_19[] PROGMEM = "INFO: verifying peer X.509 certificate...";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_20[] PROGMEM = "ERROR: failed to verify peer certificate!";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_21[] PROGMEM = "INFO: certificate verified";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_22[] PROGMEM = "INFO: cleaning SSL connection";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_23[] PROGMEM = "ERROR: fingerprint too short";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_24[] PROGMEM = "ERROR: invalid hex sequence";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_25[] PROGMEM = "ERROR: could not fetch peer certificate";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_26[] PROGMEM = "ERROR: fingerprint doesn't match";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_27[] PROGMEM = "ERROR: waiting incoming data failed!";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_28[] PROGMEM = "ERROR: reading incoming data failed!";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_29[] PROGMEM = "EHLO DUDE\r\n";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_30[] PROGMEM = "INFO: send SMTP command extended HELO";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_31[] PROGMEM = "ERROR: send SMTP command failed!";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_32[] PROGMEM = "ERROR: waiting incoming data failed!";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_33[] PROGMEM = "ERROR: reading incoming data failed!";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_34[] PROGMEM = "STARTTLS\r\n";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_35[] PROGMEM = "INFO: send STARTTLS protocol command";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_36[] PROGMEM = "ERROR: send STARTTLS protocol command failed!";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_37[] PROGMEM = "ERROR: waiting incoming data failed!";
|
||||||
|
static const char ESP32_SSL_CLIENT_STR_38[] PROGMEM = "ERROR: reading incoming data failed!";
|
||||||
|
|
||||||
|
typedef void (*DebugMsgCallback)(const char *msg);
|
||||||
|
|
||||||
|
typedef struct sslclient_context32 {
|
||||||
|
int socket;
|
||||||
|
bool starttls;
|
||||||
|
mbedtls_ssl_context ssl_ctx;
|
||||||
|
mbedtls_ssl_config ssl_conf;
|
||||||
|
mbedtls_net_context server_fd;
|
||||||
|
|
||||||
|
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;
|
||||||
|
DebugMsgCallback _debugCallback;
|
||||||
|
|
||||||
|
unsigned long handshake_timeout;
|
||||||
|
} sslclient_context32;
|
||||||
|
|
||||||
|
|
||||||
|
void ssl_init(sslclient_context32 *ssl_client);
|
||||||
|
int start_ssl_client(sslclient_context32 *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(sslclient_context32 *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||||
|
int data_to_read(sslclient_context32 *ssl_client);
|
||||||
|
int send_ssl_data(sslclient_context32 *ssl_client, const uint8_t *data, uint16_t len);
|
||||||
|
int get_ssl_receive(sslclient_context32 *ssl_client, uint8_t *data, int length);
|
||||||
|
bool verify_ssl_fingerprint(sslclient_context32 *ssl_client, const char* fp, const char* domain_name);
|
||||||
|
bool verify_ssl_dn(sslclient_context32 *ssl_client, const char* domain_name);
|
||||||
|
int starttlsHandshake(sslclient_context32 *ssl_client, int port);
|
||||||
|
void ESP32SSLClientDebugInfo(PGM_P info, sslclient_context32 *ssl_client);
|
||||||
|
|
||||||
|
#endif //ESP32
|
||||||
|
|
||||||
|
#endif //SSL_CLIENT32_H
|
@ -28,6 +28,9 @@
|
|||||||
|
|
||||||
#include <Esp.h>
|
#include <Esp.h>
|
||||||
|
|
||||||
|
|
||||||
|
// webcam uses channel 0, so we offset standard PWM
|
||||||
|
#define PWM_CHANNEL_OFFSET 2
|
||||||
// Analog
|
// Analog
|
||||||
|
|
||||||
uint8_t pwm_channel[8]={99,99,99,99,99,99,99,99};
|
uint8_t pwm_channel[8]={99,99,99,99,99,99,99,99};
|
||||||
@ -44,8 +47,8 @@ inline uint32_t pin2chan(uint32_t pin) {
|
|||||||
inline void analogWrite(uint8_t pin, int val)
|
inline void analogWrite(uint8_t pin, int val)
|
||||||
{
|
{
|
||||||
uint32_t channel=pin2chan(pin);
|
uint32_t channel=pin2chan(pin);
|
||||||
ledcWrite(channel,val);
|
ledcWrite(channel+PWM_CHANNEL_OFFSET,val);
|
||||||
Serial.printf("write %d - %d\n",channel,val);
|
//Serial.printf("write %d - %d\n",channel,val);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void analogWriteFreq(uint32_t freq)
|
inline void analogWriteFreq(uint32_t freq)
|
||||||
@ -57,8 +60,8 @@ inline void analogWriteRange(uint32_t range)
|
|||||||
|
|
||||||
inline void analogAttach(uint32_t pin, uint32_t channel) {
|
inline void analogAttach(uint32_t pin, uint32_t channel) {
|
||||||
pwm_channel[channel&7]=pin;
|
pwm_channel[channel&7]=pin;
|
||||||
ledcAttachPin(pin,channel);
|
ledcAttachPin(pin,channel+PWM_CHANNEL_OFFSET);
|
||||||
Serial.printf("attach %d - %d\n",channel,pin);
|
//Serial.printf("attach %d - %d\n",channel,pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t pow2(uint32_t x) {
|
inline uint32_t pow2(uint32_t x) {
|
||||||
@ -74,7 +77,7 @@ inline void analogWriteFreqRange(uint32_t channel,uint32_t freq, uint32_t irange
|
|||||||
uint32_t range=pow2(irange);
|
uint32_t range=pow2(irange);
|
||||||
for (uint32_t cnt=0;cnt<8;cnt++) {
|
for (uint32_t cnt=0;cnt<8;cnt++) {
|
||||||
if (pwm_channel[cnt]<99) {
|
if (pwm_channel[cnt]<99) {
|
||||||
ledcSetup(cnt,freq,range);
|
ledcSetup(cnt+PWM_CHANNEL_OFFSET,freq,range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Serial.printf("freq - range %d - %d\n",freq,range);
|
Serial.printf("freq - range %d - %d\n",freq,range);
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL - RX"
|
#define D_SENSOR_HRXL_RX "HRXL - RX"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL - TX"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL - TX"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "А"
|
#define D_UNIT_AMPERE "А"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "А"
|
#define D_UNIT_AMPERE "А"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "安"
|
#define D_UNIT_AMPERE "安"
|
||||||
|
@ -666,6 +666,27 @@
|
|||||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||||
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
|
||||||
#define D_SENSOR_AS3935 "AS3935"
|
#define D_SENSOR_AS3935 "AS3935"
|
||||||
|
#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
|
||||||
|
#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
|
||||||
|
#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
|
||||||
|
#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
|
||||||
|
#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
|
||||||
|
#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
|
||||||
|
#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
|
||||||
|
#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
|
||||||
|
#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
|
||||||
|
#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
|
||||||
|
#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
|
||||||
|
#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
|
||||||
|
#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
|
||||||
|
#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
|
||||||
|
#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
|
||||||
|
#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
|
||||||
|
#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
|
||||||
|
#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
|
||||||
|
#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
|
||||||
|
#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
|
||||||
|
#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "安"
|
#define D_UNIT_AMPERE "安"
|
||||||
|
@ -41,6 +41,7 @@ class SendEmail
|
|||||||
public:
|
public:
|
||||||
SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used);
|
SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used);
|
||||||
bool send(const String& from, const String& to, const String& subject, const char *msg);
|
bool send(const String& from, const String& to, const String& subject, const char *msg);
|
||||||
|
void send_message_txt(char *msg);
|
||||||
~SendEmail() {client->stop(); delete client;}
|
~SendEmail() {client->stop(); delete client;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#ifdef USE_SENDMAIL
|
#ifdef USE_SENDMAIL
|
||||||
|
|
||||||
|
#ifndef USE_ESP32MAIL
|
||||||
|
|
||||||
#include "sendemail.h"
|
#include "sendemail.h"
|
||||||
|
|
||||||
// enable serial debugging
|
// enable serial debugging
|
||||||
@ -26,6 +28,8 @@
|
|||||||
#define SEND_MAIL_MINRAM 12*1024
|
#define SEND_MAIL_MINRAM 12*1024
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void script_send_email_body(void(*func)(char *));
|
||||||
|
|
||||||
#define xPSTR(a) a
|
#define xPSTR(a) a
|
||||||
|
|
||||||
uint16_t SendMail(char *buffer) {
|
uint16_t SendMail(char *buffer) {
|
||||||
@ -47,7 +51,7 @@ uint16_t SendMail(char *buffer) {
|
|||||||
|
|
||||||
|
|
||||||
// return if not enough memory
|
// return if not enough memory
|
||||||
uint16_t mem=ESP_getFreeHeap();
|
uint16_t mem=ESP.getFreeHeap();
|
||||||
if (mem<SEND_MAIL_MINRAM) {
|
if (mem<SEND_MAIL_MINRAM) {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
@ -174,13 +178,15 @@ exit:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
void script_send_email_body(BearSSL::WiFiClientSecure_light *client);
|
WiFiClient *g_client;
|
||||||
SendEmail::SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used) :
|
SendEmail::SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used) :
|
||||||
host(host), port(port), user(user), passwd(passwd), timeout(timeout), ssl(ssl), auth_used(auth_used), client(new BearSSL::WiFiClientSecure_light(1024,1024)) {
|
host(host), port(port), user(user), passwd(passwd), timeout(timeout), ssl(ssl), auth_used(auth_used), client(new BearSSL::WiFiClientSecure_light(1024,1024)) {
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void script_send_email_body(WiFiClient *client);
|
WiFiClient *g_client;
|
||||||
SendEmail::SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used) :
|
SendEmail::SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used) :
|
||||||
host(host), port(port), user(user), passwd(passwd), timeout(timeout), ssl(ssl), auth_used(auth_used), client(new WiFiClientSecure()) {
|
host(host), port(port), user(user), passwd(passwd), timeout(timeout), ssl(ssl), auth_used(auth_used), client(new WiFiClientSecure()) {
|
||||||
}
|
}
|
||||||
@ -346,7 +352,8 @@ String buffer;
|
|||||||
|
|
||||||
#ifdef USE_SCRIPT
|
#ifdef USE_SCRIPT
|
||||||
if (*msg=='*' && *(msg+1)==0) {
|
if (*msg=='*' && *(msg+1)==0) {
|
||||||
script_send_email_body(client);
|
g_client=client;
|
||||||
|
script_send_email_body(xsend_message_txt);
|
||||||
} else {
|
} else {
|
||||||
client->println(msg);
|
client->println(msg);
|
||||||
}
|
}
|
||||||
@ -370,5 +377,289 @@ exit:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xsend_message_txt(char *msg) {
|
||||||
|
g_client->println(msg);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Created by K. Suwatchai (Mobizt)
|
||||||
|
*
|
||||||
|
* Email: k_suwatchai@hotmail.com
|
||||||
|
*
|
||||||
|
* Github: https://github.com/mobizt
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 mobizt
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1
|
||||||
|
|
||||||
|
//To receive Email for Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en
|
||||||
|
|
||||||
|
#include "ESP32_MailClient.h"
|
||||||
|
#include "SD.h"
|
||||||
|
|
||||||
|
//For demo only
|
||||||
|
//#include "image.h"
|
||||||
|
|
||||||
|
#ifndef SEND_MAIL32_MINRAM
|
||||||
|
#define SEND_MAIL32_MINRAM 30*1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void script_send_email_body(void(*func)(char *));
|
||||||
|
|
||||||
|
#define xPSTR(a) a
|
||||||
|
//The Email Sending data object contains config and data to send
|
||||||
|
SMTPData smtpData;
|
||||||
|
|
||||||
|
//Callback function to get the Email sending status
|
||||||
|
//void sendCallback(SendStatus info);
|
||||||
|
//#define DEBUG_EMAIL_PORT
|
||||||
|
|
||||||
|
uint16_t SendMail(char *buffer) {
|
||||||
|
char *params,*oparams;
|
||||||
|
const char *mserv;
|
||||||
|
uint16_t port;
|
||||||
|
const char *user;
|
||||||
|
const char *pstr;
|
||||||
|
const char *passwd;
|
||||||
|
const char *from;
|
||||||
|
const char *to;
|
||||||
|
const char *subject;
|
||||||
|
const char *cmd;
|
||||||
|
uint16_t status=1;
|
||||||
|
uint16_t blen;
|
||||||
|
char *endcmd;
|
||||||
|
|
||||||
|
// return if not enough memory
|
||||||
|
uint32_t mem=ESP.getFreeHeap();
|
||||||
|
AddLog_P2(LOG_LEVEL_INFO, PSTR("heap: %d"),mem);
|
||||||
|
if (mem<SEND_MAIL32_MINRAM) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*buffer==' ') buffer++;
|
||||||
|
|
||||||
|
if (*buffer!='[') {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer++;
|
||||||
|
|
||||||
|
endcmd=strchr(buffer,']');
|
||||||
|
if (!endcmd) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy params
|
||||||
|
blen=(uint32_t)endcmd-(uint32_t)buffer;
|
||||||
|
oparams=(char*)calloc(blen+2,1);
|
||||||
|
if (!oparams) return 4;
|
||||||
|
params=oparams;
|
||||||
|
strncpy(oparams,buffer,blen+2);
|
||||||
|
oparams[blen]=0;
|
||||||
|
|
||||||
|
cmd=endcmd+1;
|
||||||
|
|
||||||
|
#ifdef DEBUG_EMAIL_PORT
|
||||||
|
AddLog_P2(LOG_LEVEL_INFO, PSTR("mailsize: %d"),blen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mserv=strtok(params,":");
|
||||||
|
if (!mserv) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// port
|
||||||
|
pstr=strtok(NULL,":");
|
||||||
|
if (!pstr) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EMAIL_PORT
|
||||||
|
if (*pstr=='*') {
|
||||||
|
port=EMAIL_PORT;
|
||||||
|
} else {
|
||||||
|
port=atoi(pstr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
port=atoi(pstr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
user=strtok(NULL,":");
|
||||||
|
if (!user) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
passwd=strtok(NULL,":");
|
||||||
|
if (!passwd) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
from=strtok(NULL,":");
|
||||||
|
if (!from) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
to=strtok(NULL,":");
|
||||||
|
if (!to) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
subject=strtok(NULL,"]");
|
||||||
|
if (!subject) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef EMAIL_USER
|
||||||
|
if (*user=='*') {
|
||||||
|
user=xPSTR(EMAIL_USER);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef EMAIL_PASSWORD
|
||||||
|
if (*passwd=='*') {
|
||||||
|
passwd=xPSTR(EMAIL_PASSWORD);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef EMAIL_SERVER
|
||||||
|
if (*mserv=='*') {
|
||||||
|
mserv=xPSTR(EMAIL_SERVER);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_EMAIL_PORT
|
||||||
|
AddLog_P2(LOG_LEVEL_INFO, PSTR("%s - %d - %s - %s"),mserv,port,user,passwd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EMAIL_FROM
|
||||||
|
if (*from=='*') {
|
||||||
|
from=xPSTR(EMAIL_FROM);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_EMAIL_PORT
|
||||||
|
AddLog_P2(LOG_LEVEL_INFO, PSTR("%s - %s - %s - %s"),from,to,subject,cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
smtpData.setDebug(true);
|
||||||
|
|
||||||
|
//Set the Email host, port, account and password
|
||||||
|
smtpData.setLogin(mserv, port, user, passwd);
|
||||||
|
|
||||||
|
//For library version 1.2.0 and later which STARTTLS protocol was supported,the STARTTLS will be
|
||||||
|
//enabled automatically when port 587 was used, or enable it manually using setSTARTTLS function.
|
||||||
|
//smtpData.setSTARTTLS(true);
|
||||||
|
|
||||||
|
//Set the sender name and Email
|
||||||
|
smtpData.setSender("ESP32",from);
|
||||||
|
|
||||||
|
//Set Email priority or importance High, Normal, Low or 1 to 5 (1 is highest)
|
||||||
|
smtpData.setPriority("High");
|
||||||
|
|
||||||
|
//Set the subject
|
||||||
|
smtpData.setSubject(subject);
|
||||||
|
|
||||||
|
#ifdef USE_SCRIPT
|
||||||
|
if (*cmd=='*' && *(cmd+1)==0) {
|
||||||
|
smtpData.clrMessage(true);
|
||||||
|
script_send_email_body(send_message_txt);
|
||||||
|
} else {
|
||||||
|
smtpData.setMessage(cmd, true);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
//Set the message - normal text or html format
|
||||||
|
smtpData.setMessage(cmd, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//Add recipients, can add more than one recipient
|
||||||
|
smtpData.addRecipient(to);
|
||||||
|
|
||||||
|
//Add attachments, can add the file or binary data from flash memory, file in SD card
|
||||||
|
//Data from internal memory
|
||||||
|
//smtpData.addAttachData("firebase_logo.png", "image/png", (uint8_t *)dummyImageData, sizeof dummyImageData);
|
||||||
|
|
||||||
|
//Add attach files from SD card
|
||||||
|
//Comment these two lines, if no SD card connected
|
||||||
|
//Two files that previousely created.
|
||||||
|
//smtpData.addAttachFile("/binary_file.dat");
|
||||||
|
//smtpData.addAttachFile("/text_file.txt");
|
||||||
|
|
||||||
|
|
||||||
|
//Add some custom header to message
|
||||||
|
//See https://tools.ietf.org/html/rfc822
|
||||||
|
//These header fields can be read from raw or source of message when it received)
|
||||||
|
//smtpData.addCustomMessageHeader("Date: Sat, 10 Aug 2019 21:39:56 -0700 (PDT)");
|
||||||
|
//Be careful when set Message-ID, it should be unique, otherwise message will not store
|
||||||
|
//smtpData.addCustomMessageHeader("Message-ID: <abcde.fghij@gmail.com>");
|
||||||
|
|
||||||
|
//Set the storage types to read the attach files (SD is default)
|
||||||
|
//smtpData.setFileStorageType(MailClientStorageType::SPIFFS);
|
||||||
|
#if defined (USE_SCRIPT) && defined(USE_SCRIPT_FATFS)
|
||||||
|
smtpData.setFileStorageType(MailClientStorageType::SD);
|
||||||
|
#endif
|
||||||
|
//smtpData.setSendCallback(sendCallback);
|
||||||
|
|
||||||
|
//Start sending Email, can be set callback function to track the status
|
||||||
|
if (!MailClient.sendMail(smtpData)) {
|
||||||
|
//Serial.println("Error sending Email, " + MailClient.smtpErrorReason());
|
||||||
|
AddLog_P2(LOG_LEVEL_INFO, PSTR("Error sending Email, %s"), MailClient.smtpErrorReason());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
status=0;
|
||||||
|
}
|
||||||
|
//Clear all data from Email object to free memory
|
||||||
|
smtpData.empty();
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (oparams) free(oparams);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_message_txt(char *txt) {
|
||||||
|
if (*txt=='&') {
|
||||||
|
txt++;
|
||||||
|
smtpData.addAttachFile(txt);
|
||||||
|
} else if (*txt=='$') {
|
||||||
|
txt++;
|
||||||
|
#if defined(ESP32) && defined(USE_WEBCAM)
|
||||||
|
uint32_t cnt;
|
||||||
|
uint8_t *buff;
|
||||||
|
uint32_t len,picmax;
|
||||||
|
picmax=get_picstore(-1,0);
|
||||||
|
cnt=*txt&7;
|
||||||
|
if (cnt<1 || cnt>picmax) cnt=1;
|
||||||
|
len=get_picstore(cnt-1,&buff);
|
||||||
|
if (len) {
|
||||||
|
char str[12];
|
||||||
|
sprintf(str,"img_%1d.jpg",cnt+1);
|
||||||
|
smtpData.addAttachData(str, "image/jpg",buff,len);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
smtpData.addMessage(txt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
//Callback function to get the Email sending status
|
||||||
|
void sendCallback(SendStatus msg)
|
||||||
|
{
|
||||||
|
//Print the current status
|
||||||
|
Serial.println(msg.info());
|
||||||
|
|
||||||
|
//Do something when complete
|
||||||
|
if (msg.success())
|
||||||
|
{
|
||||||
|
Serial.println("----------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // USE_SENDMAIL
|
#endif // USE_SENDMAIL
|
||||||
|
@ -197,6 +197,28 @@ enum UserSelectablePins {
|
|||||||
ADC0_BUTTON_INV,
|
ADC0_BUTTON_INV,
|
||||||
ADC0_RANGE, // Range
|
ADC0_RANGE, // Range
|
||||||
ADC0_CT_POWER, // Current
|
ADC0_CT_POWER, // Current
|
||||||
|
// webcam interface
|
||||||
|
GPIO_WEBCAM_PWDN_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_RESET_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_XCLK_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_SIOD_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_SIOC_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_Y9_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_Y8_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_Y7_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_Y6_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_Y5_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_Y4_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_Y3_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_Y2_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_VSYNC_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_HREF_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_PCLK_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_PSCLK_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_HSD1_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_HSD2_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_HSD3_GPIO_NUM,
|
||||||
|
GPIO_WEBCAM_PSRCS_GPIO_NUM,
|
||||||
GPIO_SENSOR_END };
|
GPIO_SENSOR_END };
|
||||||
|
|
||||||
enum ProgramSelectablePins {
|
enum ProgramSelectablePins {
|
||||||
@ -287,6 +309,27 @@ const char kSensorNames[] PROGMEM =
|
|||||||
D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "i|"
|
D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "i|"
|
||||||
D_RANGE "|"
|
D_RANGE "|"
|
||||||
D_CT_POWER "|"
|
D_CT_POWER "|"
|
||||||
|
D_GPIO_WEBCAM_PWDN_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_RESET_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_XCLK_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_SIOD_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_SIOC_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_Y9_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_Y8_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_Y7_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_Y6_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_Y5_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_Y4_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_Y3_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_Y2_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_VSYNC_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_HREF_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_PCLK_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_PSCLK_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_HSD1_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_HSD2_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_HSD3_GPIO_NUM "|"
|
||||||
|
D_GPIO_WEBCAM_PSRCS_GPIO_NUM
|
||||||
;
|
;
|
||||||
|
|
||||||
const char kSensorNamesFixed[] PROGMEM =
|
const char kSensorNamesFixed[] PROGMEM =
|
||||||
@ -589,6 +632,29 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
|||||||
AGPIO(ADC0_CT_POWER), // Current
|
AGPIO(ADC0_CT_POWER), // Current
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
#if defined(ESP32) && defined(USE_WEBCAM)
|
||||||
|
AGPIO(GPIO_WEBCAM_PWDN_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_RESET_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_XCLK_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_SIOD_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_SIOC_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_Y9_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_Y8_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_Y7_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_Y6_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_Y5_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_Y4_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_Y3_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_Y2_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_VSYNC_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_HREF_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_PCLK_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_PSCLK_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_HSD1_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_HSD2_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_HSD3_GPIO_NUM),
|
||||||
|
AGPIO(GPIO_WEBCAM_PSRCS_GPIO_NUM),
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//********************************************************************************************
|
//********************************************************************************************
|
||||||
|
@ -62,6 +62,7 @@ keywords if then else endif, or, and are better readable for beginners (others m
|
|||||||
#define MAX_SCRIPT_SIZE MAX_RULE_SIZE*MAX_RULE_SETS
|
#define MAX_SCRIPT_SIZE MAX_RULE_SIZE*MAX_RULE_SETS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t EncodeLightId(uint8_t relay_id);
|
uint32_t EncodeLightId(uint8_t relay_id);
|
||||||
uint32_t DecodeLightId(uint32_t hue_id);
|
uint32_t DecodeLightId(uint32_t hue_id);
|
||||||
|
|
||||||
@ -102,14 +103,36 @@ enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD};
|
|||||||
|
|
||||||
#ifdef USE_SCRIPT_FATFS
|
#ifdef USE_SCRIPT_FATFS
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
|
//#define USE_MMC
|
||||||
|
|
||||||
|
#ifdef USE_MMC
|
||||||
|
#include <SD_MMC.h>
|
||||||
|
#undef FS_USED
|
||||||
|
#define FS_USED SD_MMC
|
||||||
|
#else
|
||||||
#include <SD.h>
|
#include <SD.h>
|
||||||
|
#undef FS_USED
|
||||||
|
#define FS_USED SD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ESP32
|
||||||
|
#undef FILE_WRITE
|
||||||
|
#define FILE_WRITE (sdfat::O_READ | sdfat::O_WRITE | sdfat::O_CREAT)
|
||||||
|
#define FILE_APPEND (sdfat::O_READ | sdfat::O_WRITE | sdfat::O_CREAT | sdfat::O_APPEND)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FAT_SCRIPT_SIZE
|
#ifndef FAT_SCRIPT_SIZE
|
||||||
#define FAT_SCRIPT_SIZE 4096
|
#define FAT_SCRIPT_SIZE 4096
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ESP32
|
||||||
|
#undef FAT_SCRIPT_NAME
|
||||||
|
#define FAT_SCRIPT_NAME "/script.txt"
|
||||||
|
#else
|
||||||
|
#undef FAT_SCRIPT_NAME
|
||||||
#define FAT_SCRIPT_NAME "script.txt"
|
#define FAT_SCRIPT_NAME "script.txt"
|
||||||
#if USE_LONG_FILE_NAMES==1
|
|
||||||
#warning ("FATFS long filenames not supported");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_STANDARD_SPI_LIBRARY==0
|
#if USE_STANDARD_SPI_LIBRARY==0
|
||||||
#warning ("FATFS standard spi should be used");
|
#warning ("FATFS standard spi should be used");
|
||||||
#endif
|
#endif
|
||||||
@ -266,7 +289,6 @@ void RulesTeleperiod(void) {
|
|||||||
#define EEP_SCRIPT_SIZE 4095
|
#define EEP_SCRIPT_SIZE 4095
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static Eeprom24C128_256 eeprom(EEPROM_ADDRESS);
|
static Eeprom24C128_256 eeprom(EEPROM_ADDRESS);
|
||||||
// eeprom.writeBytes(address, length, buffer);
|
// eeprom.writeBytes(address, length, buffer);
|
||||||
#define EEP_WRITE(A,B,C) eeprom.writeBytes(A,B,(uint8_t*)C);
|
#define EEP_WRITE(A,B,C) eeprom.writeBytes(A,B,(uint8_t*)C);
|
||||||
@ -588,7 +610,11 @@ char *script;
|
|||||||
|
|
||||||
#ifdef USE_SCRIPT_FATFS
|
#ifdef USE_SCRIPT_FATFS
|
||||||
if (!glob_script_mem.script_sd_found) {
|
if (!glob_script_mem.script_sd_found) {
|
||||||
if (SD.begin(USE_SCRIPT_FATFS)) {
|
#ifdef USE_MMC
|
||||||
|
if (FS_USED.begin()) {
|
||||||
|
#else
|
||||||
|
if (FS_USED.begin(USE_SCRIPT_FATFS)) {
|
||||||
|
#endif
|
||||||
glob_script_mem.script_sd_found=1;
|
glob_script_mem.script_sd_found=1;
|
||||||
} else {
|
} else {
|
||||||
glob_script_mem.script_sd_found=0;
|
glob_script_mem.script_sd_found=0;
|
||||||
@ -1166,20 +1192,36 @@ chknext:
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef USE_SCRIPT_FATFS
|
|
||||||
case 'f':
|
case 'f':
|
||||||
|
#ifdef USE_SCRIPT_FATFS
|
||||||
if (!strncmp(vname,"fo(",3)) {
|
if (!strncmp(vname,"fo(",3)) {
|
||||||
lp+=3;
|
lp+=3;
|
||||||
char str[SCRIPT_MAXSSIZE];
|
char str[SCRIPT_MAXSSIZE];
|
||||||
lp=GetStringResult(lp,OPER_EQU,str,0);
|
lp=GetStringResult(lp,OPER_EQU,str,0);
|
||||||
while (*lp==' ') lp++;
|
while (*lp==' ') lp++;
|
||||||
lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
|
uint8_t mode=0;
|
||||||
uint8_t mode=fvar;
|
if ((*lp=='r') || (*lp=='w') || (*lp=='a')) {
|
||||||
|
switch (*lp) {
|
||||||
|
case 'r':
|
||||||
|
mode=0;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
mode=1;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
mode=2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lp++;
|
||||||
|
} else {
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
|
||||||
|
mode=fvar;
|
||||||
|
}
|
||||||
fvar=-1;
|
fvar=-1;
|
||||||
for (uint8_t cnt=0;cnt<SFS_MAX;cnt++) {
|
for (uint8_t cnt=0;cnt<SFS_MAX;cnt++) {
|
||||||
if (!glob_script_mem.file_flags[cnt].is_open) {
|
if (!glob_script_mem.file_flags[cnt].is_open) {
|
||||||
if (mode==0) {
|
if (mode==0) {
|
||||||
glob_script_mem.files[cnt]=SD.open(str,FILE_READ);
|
glob_script_mem.files[cnt]=FS_USED.open(str,FILE_READ);
|
||||||
if (glob_script_mem.files[cnt].isDirectory()) {
|
if (glob_script_mem.files[cnt].isDirectory()) {
|
||||||
glob_script_mem.files[cnt].rewindDirectory();
|
glob_script_mem.files[cnt].rewindDirectory();
|
||||||
glob_script_mem.file_flags[cnt].is_dir=1;
|
glob_script_mem.file_flags[cnt].is_dir=1;
|
||||||
@ -1187,7 +1229,13 @@ chknext:
|
|||||||
glob_script_mem.file_flags[cnt].is_dir=0;
|
glob_script_mem.file_flags[cnt].is_dir=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else glob_script_mem.files[cnt]=SD.open(str,FILE_WRITE);
|
else {
|
||||||
|
if (mode==1) {
|
||||||
|
glob_script_mem.files[cnt]=FS_USED.open(str,FILE_WRITE);
|
||||||
|
} else {
|
||||||
|
glob_script_mem.files[cnt]=FS_USED.open(str,FILE_APPEND);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (glob_script_mem.files[cnt]) {
|
if (glob_script_mem.files[cnt]) {
|
||||||
fvar=cnt;
|
fvar=cnt;
|
||||||
glob_script_mem.file_flags[cnt].is_open=1;
|
glob_script_mem.file_flags[cnt].is_open=1;
|
||||||
@ -1275,7 +1323,13 @@ chknext:
|
|||||||
File entry=glob_script_mem.files[find].openNextFile();
|
File entry=glob_script_mem.files[find].openNextFile();
|
||||||
if (entry) {
|
if (entry) {
|
||||||
if (!reject((char*)entry.name())) {
|
if (!reject((char*)entry.name())) {
|
||||||
strcpy(str,entry.name());
|
char *ep=(char*)entry.name();
|
||||||
|
if (*ep=='/') ep++;
|
||||||
|
char *lcp = strrchr(ep,'/');
|
||||||
|
if (lcp) {
|
||||||
|
ep=lcp+1;
|
||||||
|
}
|
||||||
|
strcpy(str,ep);
|
||||||
entry.close();
|
entry.close();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1313,18 +1367,47 @@ chknext:
|
|||||||
lp+=3;
|
lp+=3;
|
||||||
char str[glob_script_mem.max_ssize+1];
|
char str[glob_script_mem.max_ssize+1];
|
||||||
lp=GetStringResult(lp,OPER_EQU,str,0);
|
lp=GetStringResult(lp,OPER_EQU,str,0);
|
||||||
SD.remove(str);
|
FS_USED.remove(str);
|
||||||
lp++;
|
lp++;
|
||||||
len=0;
|
len=0;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
#if defined(ESP32) && defined(USE_WEBCAM)
|
||||||
|
if (!strncmp(vname,"fwp(",4)) {
|
||||||
|
lp+=4;
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
|
||||||
|
while (*lp==' ') lp++;
|
||||||
|
float fvar1;
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
|
||||||
|
uint8_t ind=fvar1;
|
||||||
|
if (ind>=SFS_MAX) ind=SFS_MAX-1;
|
||||||
|
if (glob_script_mem.file_flags[ind].is_open) {
|
||||||
|
uint8_t *buff;
|
||||||
|
float maxps=get_picstore(-1,0);
|
||||||
|
if (fvar<1 || fvar>maxps) fvar=1;
|
||||||
|
uint32_t len=get_picstore(fvar-1, &buff);
|
||||||
|
if (len) {
|
||||||
|
//glob_script_mem.files[ind].seek(0,SeekEnd);
|
||||||
|
fvar=glob_script_mem.files[ind].write(buff,len);
|
||||||
|
} else {
|
||||||
|
fvar=0;
|
||||||
|
}
|
||||||
|
//AddLog_P2(LOG_LEVEL_INFO, PSTR("picture save: %d"), len);
|
||||||
|
} else {
|
||||||
|
fvar=0;
|
||||||
|
}
|
||||||
|
lp++;
|
||||||
|
len=0;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef USE_SCRIPT_FATFS_EXT
|
#ifdef USE_SCRIPT_FATFS_EXT
|
||||||
if (!strncmp(vname,"fe(",3)) {
|
if (!strncmp(vname,"fe(",3)) {
|
||||||
lp+=3;
|
lp+=3;
|
||||||
char str[glob_script_mem.max_ssize+1];
|
char str[glob_script_mem.max_ssize+1];
|
||||||
lp=GetStringResult(lp,OPER_EQU,str,0);
|
lp=GetStringResult(lp,OPER_EQU,str,0);
|
||||||
// execute script
|
// execute script
|
||||||
File ef=SD.open(str);
|
File ef=FS_USED.open(str);
|
||||||
if (ef) {
|
if (ef) {
|
||||||
uint16_t fsiz=ef.size();
|
uint16_t fsiz=ef.size();
|
||||||
if (fsiz<2048) {
|
if (fsiz<2048) {
|
||||||
@ -1346,7 +1429,7 @@ chknext:
|
|||||||
lp+=4;
|
lp+=4;
|
||||||
char str[glob_script_mem.max_ssize+1];
|
char str[glob_script_mem.max_ssize+1];
|
||||||
lp=GetStringResult(lp,OPER_EQU,str,0);
|
lp=GetStringResult(lp,OPER_EQU,str,0);
|
||||||
fvar=SD.mkdir(str);
|
fvar=FS_USED.mkdir(str);
|
||||||
lp++;
|
lp++;
|
||||||
len=0;
|
len=0;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -1355,7 +1438,7 @@ chknext:
|
|||||||
lp+=4;
|
lp+=4;
|
||||||
char str[glob_script_mem.max_ssize+1];
|
char str[glob_script_mem.max_ssize+1];
|
||||||
lp=GetStringResult(lp,OPER_EQU,str,0);
|
lp=GetStringResult(lp,OPER_EQU,str,0);
|
||||||
fvar=SD.rmdir(str);
|
fvar=FS_USED.rmdir(str);
|
||||||
lp++;
|
lp++;
|
||||||
len=0;
|
len=0;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -1364,13 +1447,13 @@ chknext:
|
|||||||
lp+=3;
|
lp+=3;
|
||||||
char str[glob_script_mem.max_ssize+1];
|
char str[glob_script_mem.max_ssize+1];
|
||||||
lp=GetStringResult(lp,OPER_EQU,str,0);
|
lp=GetStringResult(lp,OPER_EQU,str,0);
|
||||||
if (SD.exists(str)) fvar=1;
|
if (FS_USED.exists(str)) fvar=1;
|
||||||
else fvar=0;
|
else fvar=0;
|
||||||
lp++;
|
lp++;
|
||||||
len=0;
|
len=0;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // USE_SCRIPT_FATFS_EXT
|
||||||
if (!strncmp(vname,"fl1(",4) || !strncmp(vname,"fl2(",4) ) {
|
if (!strncmp(vname,"fl1(",4) || !strncmp(vname,"fl2(",4) ) {
|
||||||
uint8_t lknum=*(lp+2)&3;
|
uint8_t lknum=*(lp+2)&3;
|
||||||
lp+=4;
|
lp+=4;
|
||||||
@ -1388,9 +1471,16 @@ chknext:
|
|||||||
//card_init();
|
//card_init();
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
#endif //USE_SCRIPT_FATFS
|
#endif //USE_SCRIPT_FATFS
|
||||||
|
if (!strncmp(vname,"freq",4)) {
|
||||||
|
#ifdef ESP32
|
||||||
|
fvar=getCpuFrequencyMhz();
|
||||||
|
#else
|
||||||
|
fvar=ESP.getCpuFreqMHz();
|
||||||
|
#endif
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
if (!strncmp(vname,"gtmp",4)) {
|
if (!strncmp(vname,"gtmp",4)) {
|
||||||
fvar=global_temperature;
|
fvar=global_temperature;
|
||||||
@ -1573,6 +1663,13 @@ chknext:
|
|||||||
}
|
}
|
||||||
if (!strncmp(vname,"pn[",3)) {
|
if (!strncmp(vname,"pn[",3)) {
|
||||||
GetNumericResult(vname+3,OPER_EQU,&fvar,0);
|
GetNumericResult(vname+3,OPER_EQU,&fvar,0);
|
||||||
|
fvar=Pin(fvar);
|
||||||
|
// skip ] bracket
|
||||||
|
len++;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (!strncmp(vname,"pn[",3)) {
|
||||||
|
GetNumericResult(vname+3,OPER_EQU,&fvar,0);
|
||||||
// fvar=pin_gpio[(uint8_t)fvar];
|
// fvar=pin_gpio[(uint8_t)fvar];
|
||||||
fvar=Pin(fvar);
|
fvar=Pin(fvar);
|
||||||
// skip ] bracket
|
// skip ] bracket
|
||||||
@ -1790,7 +1887,7 @@ chknext:
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SML_SCRIPT_CMD
|
#if defined(USE_SML_M) && defined (USE_SML_SCRIPT_CMD)
|
||||||
if (!strncmp(vname,"sml(",4)) {
|
if (!strncmp(vname,"sml(",4)) {
|
||||||
lp+=4;
|
lp+=4;
|
||||||
float fvar1;
|
float fvar1;
|
||||||
@ -1902,6 +1999,60 @@ chknext:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'w':
|
case 'w':
|
||||||
|
#if defined(ESP32) && defined(USE_WEBCAM)
|
||||||
|
if (!strncmp(vname,"wc(",3)) {
|
||||||
|
lp+=3;
|
||||||
|
float fvar1;
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
|
||||||
|
SCRIPT_SKIP_SPACES
|
||||||
|
switch ((uint32)fvar1) {
|
||||||
|
case 0:
|
||||||
|
{ float fvar2;
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
|
||||||
|
fvar=wc_setup(fvar2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
{ float fvar2;
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
|
||||||
|
fvar=wc_get_frame(fvar2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
{ float fvar2,fvar3;
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
|
||||||
|
SCRIPT_SKIP_SPACES
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar3,0);
|
||||||
|
fvar=wc_set_options(fvar2,fvar3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
fvar=wc_get_width();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
fvar=wc_get_height();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
{ float fvar2;
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
|
||||||
|
fvar=wc_set_streamserver(fvar2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
{ float fvar2;
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
|
||||||
|
fvar=wc_set_motion_detect(fvar2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fvar=0;
|
||||||
|
}
|
||||||
|
lp++;
|
||||||
|
len=0;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (!strncmp(vname,"wday",4)) {
|
if (!strncmp(vname,"wday",4)) {
|
||||||
fvar=RtcTime.day_of_week;
|
fvar=RtcTime.day_of_week;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -2722,9 +2873,29 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||||||
lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
|
lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
|
||||||
int8_t pinnr=fvar;
|
int8_t pinnr=fvar;
|
||||||
SCRIPT_SKIP_SPACES
|
SCRIPT_SKIP_SPACES
|
||||||
lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
|
uint8_t mode=0;
|
||||||
int8_t mode=fvar;
|
if ((*lp=='I') || (*lp=='O') || (*lp=='P')) {
|
||||||
pinMode(pinnr,mode&3);
|
switch (*lp) {
|
||||||
|
case 'I':
|
||||||
|
mode=0;
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
mode=1;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
mode=2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lp++;
|
||||||
|
} else {
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
|
||||||
|
mode=fvar;
|
||||||
|
}
|
||||||
|
uint8_t pm=0;
|
||||||
|
if (mode==0) pm=INPUT;
|
||||||
|
if (mode==1) pm=OUTPUT;
|
||||||
|
if (mode==2) pm=INPUT_PULLUP;
|
||||||
|
pinMode(pinnr,pm);
|
||||||
goto next_line;
|
goto next_line;
|
||||||
} else if (!strncmp(lp,"spin(",5)) {
|
} else if (!strncmp(lp,"spin(",5)) {
|
||||||
lp+=5;
|
lp+=5;
|
||||||
@ -2763,6 +2934,21 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||||||
goto next_line;
|
goto next_line;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef ESP32
|
||||||
|
else if (!strncmp(lp,"beep(",5)) {
|
||||||
|
lp+=5;
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
|
||||||
|
if (fvar<0) {
|
||||||
|
ledcSetup(7,500,10);
|
||||||
|
ledcAttachPin(-fvar,7);
|
||||||
|
ledcWriteTone(7,0);
|
||||||
|
} else {
|
||||||
|
ledcWriteTone(7,fvar);
|
||||||
|
}
|
||||||
|
lp++;
|
||||||
|
goto next_line;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2) || !strncmp(lp,"+>",2) || !strncmp(lp,"print",5)) {
|
else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2) || !strncmp(lp,"+>",2) || !strncmp(lp,"print",5)) {
|
||||||
@ -3274,7 +3460,7 @@ const char HTTP_FORM_FILE_UPGb[] PROGMEM =
|
|||||||
const char HTTP_FORM_SDC_DIRa[] PROGMEM =
|
const char HTTP_FORM_SDC_DIRa[] PROGMEM =
|
||||||
"<div style='text-align:left'>";
|
"<div style='text-align:left'>";
|
||||||
const char HTTP_FORM_SDC_DIRb[] PROGMEM =
|
const char HTTP_FORM_SDC_DIRb[] PROGMEM =
|
||||||
"<pre><a href='%s' file='%s'>%s</a> %d</pre>";
|
"<pre><a href='%s' file='%s'>%s</a> %s : %8d</pre>";
|
||||||
const char HTTP_FORM_SDC_DIRd[] PROGMEM =
|
const char HTTP_FORM_SDC_DIRd[] PROGMEM =
|
||||||
"<pre><a href='%s' file='%s'>%s</a></pre>";
|
"<pre><a href='%s' file='%s'>%s</a></pre>";
|
||||||
const char HTTP_FORM_SDC_DIRc[] PROGMEM =
|
const char HTTP_FORM_SDC_DIRc[] PROGMEM =
|
||||||
@ -3297,6 +3483,7 @@ const char HTTP_FORM_SDC_HREF[] PROGMEM =
|
|||||||
|
|
||||||
uint8_t reject(char *name) {
|
uint8_t reject(char *name) {
|
||||||
|
|
||||||
|
while (*name=='/') name++;
|
||||||
if (*name=='_') return 1;
|
if (*name=='_') return 1;
|
||||||
if (*name=='.') return 1;
|
if (*name=='.') return 1;
|
||||||
|
|
||||||
@ -3311,6 +3498,8 @@ uint8_t reject(char *name) {
|
|||||||
if (!strcasecmp(name,"FSEVEN~1")) return 1;
|
if (!strcasecmp(name,"FSEVEN~1")) return 1;
|
||||||
if (!strcasecmp(name,"SYSTEM~1")) return 1;
|
if (!strcasecmp(name,"SYSTEM~1")) return 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!strncasecmp(name,"System Volume",13)) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3320,7 +3509,7 @@ void ListDir(char *path, uint8_t depth) {
|
|||||||
char format[12];
|
char format[12];
|
||||||
sprintf(format,"%%-%ds",24-depth);
|
sprintf(format,"%%-%ds",24-depth);
|
||||||
|
|
||||||
File dir=SD.open(path);
|
File dir=FS_USED.open(path);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
dir.rewindDirectory();
|
dir.rewindDirectory();
|
||||||
if (strlen(path)>1) {
|
if (strlen(path)>1) {
|
||||||
@ -3334,35 +3523,48 @@ void ListDir(char *path, uint8_t depth) {
|
|||||||
}
|
}
|
||||||
WSContentSend_P(HTTP_FORM_SDC_DIRd,npath,path,"..");
|
WSContentSend_P(HTTP_FORM_SDC_DIRd,npath,path,"..");
|
||||||
}
|
}
|
||||||
|
char *ep;
|
||||||
while (true) {
|
while (true) {
|
||||||
File entry=dir.openNextFile();
|
File entry=dir.openNextFile();
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// esp32 returns path here, shorten to filename
|
||||||
|
ep=(char*)entry.name();
|
||||||
|
if (*ep=='/') ep++;
|
||||||
|
char *lcp = strrchr(ep,'/');
|
||||||
|
if (lcp) {
|
||||||
|
ep=lcp+1;
|
||||||
|
}
|
||||||
|
//AddLog_P2(LOG_LEVEL_INFO, PSTR("entry: %s"),ep);
|
||||||
|
time_t tm=entry.getLastWrite();
|
||||||
|
char tstr[24];
|
||||||
|
strftime(tstr, 22, "%d-%m-%Y - %H:%M:%S ", localtime(&tm));
|
||||||
|
|
||||||
char *pp=path;
|
char *pp=path;
|
||||||
if (!*(pp+1)) pp++;
|
if (!*(pp+1)) pp++;
|
||||||
char *cp=name;
|
char *cp=name;
|
||||||
// osx formatted disks contain a lot of stuff we dont want
|
// osx formatted disks contain a lot of stuff we dont want
|
||||||
if (reject((char*)entry.name())) goto fclose;
|
if (reject((char*)ep)) goto fclose;
|
||||||
|
|
||||||
for (uint8_t cnt=0;cnt<depth;cnt++) {
|
for (uint8_t cnt=0;cnt<depth;cnt++) {
|
||||||
*cp++='-';
|
*cp++='-';
|
||||||
}
|
}
|
||||||
// unfortunately no time date info in class File
|
|
||||||
sprintf(cp,format,entry.name());
|
sprintf(cp,format,ep);
|
||||||
if (entry.isDirectory()) {
|
if (entry.isDirectory()) {
|
||||||
snprintf_P(npath,sizeof(npath),HTTP_FORM_SDC_HREF,WiFi.localIP().toString().c_str(),pp,entry.name());
|
snprintf_P(npath,sizeof(npath),HTTP_FORM_SDC_HREF,WiFi.localIP().toString().c_str(),pp,ep);
|
||||||
WSContentSend_P(HTTP_FORM_SDC_DIRd,npath,entry.name(),name);
|
WSContentSend_P(HTTP_FORM_SDC_DIRd,npath,ep,name);
|
||||||
uint8_t plen=strlen(path);
|
uint8_t plen=strlen(path);
|
||||||
if (plen>1) {
|
if (plen>1) {
|
||||||
strcat(path,"/");
|
strcat(path,"/");
|
||||||
}
|
}
|
||||||
strcat(path,entry.name());
|
strcat(path,ep);
|
||||||
ListDir(path,depth+4);
|
ListDir(path,depth+4);
|
||||||
path[plen]=0;
|
path[plen]=0;
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(npath,sizeof(npath),HTTP_FORM_SDC_HREF,WiFi.localIP().toString().c_str(),pp,entry.name());
|
snprintf_P(npath,sizeof(npath),HTTP_FORM_SDC_HREF,WiFi.localIP().toString().c_str(),pp,ep);
|
||||||
WSContentSend_P(HTTP_FORM_SDC_DIRb,npath,entry.name(),name,entry.size());
|
WSContentSend_P(HTTP_FORM_SDC_DIRb,npath,ep,name,tstr,entry.size());
|
||||||
}
|
}
|
||||||
fclose:
|
fclose:
|
||||||
entry.close();
|
entry.close();
|
||||||
@ -3429,8 +3631,8 @@ void script_upload(void) {
|
|||||||
if (upload.status == UPLOAD_FILE_START) {
|
if (upload.status == UPLOAD_FILE_START) {
|
||||||
char npath[48];
|
char npath[48];
|
||||||
sprintf(npath,"%s/%s",path,upload.filename.c_str());
|
sprintf(npath,"%s/%s",path,upload.filename.c_str());
|
||||||
SD.remove(npath);
|
FS_USED.remove(npath);
|
||||||
upload_file=SD.open(npath,FILE_WRITE);
|
upload_file=FS_USED.open(npath,FILE_WRITE);
|
||||||
if (!upload_file) Web.upload_error=1;
|
if (!upload_file) Web.upload_error=1;
|
||||||
} else if(upload.status == UPLOAD_FILE_WRITE) {
|
} else if(upload.status == UPLOAD_FILE_WRITE) {
|
||||||
if (upload_file) upload_file.write(upload.buf,upload.currentSize);
|
if (upload_file) upload_file.write(upload.buf,upload.currentSize);
|
||||||
@ -3449,12 +3651,12 @@ uint8_t DownloadFile(char *file) {
|
|||||||
File download_file;
|
File download_file;
|
||||||
WiFiClient download_Client;
|
WiFiClient download_Client;
|
||||||
|
|
||||||
if (!SD.exists(file)) {
|
if (!FS_USED.exists(file)) {
|
||||||
AddLog_P(LOG_LEVEL_INFO,PSTR("file not found"));
|
AddLog_P(LOG_LEVEL_INFO,PSTR("file not found"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
download_file=SD.open(file,FILE_READ);
|
download_file=FS_USED.open(file,FILE_READ);
|
||||||
if (!download_file) {
|
if (!download_file) {
|
||||||
AddLog_P(LOG_LEVEL_INFO,PSTR("could not open file"));
|
AddLog_P(LOG_LEVEL_INFO,PSTR("could not open file"));
|
||||||
return 0;
|
return 0;
|
||||||
@ -3518,6 +3720,7 @@ void HandleScriptTextareaConfiguration(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HandleScriptConfiguration(void) {
|
void HandleScriptConfiguration(void) {
|
||||||
|
|
||||||
if (!HttpCheckPriviledgedAccess()) { return; }
|
if (!HttpCheckPriviledgedAccess()) { return; }
|
||||||
@ -3619,19 +3822,17 @@ void ScriptSaveSettings(void) {
|
|||||||
|
|
||||||
strlcpy(glob_script_mem.script_ram,str.c_str(), glob_script_mem.script_size);
|
strlcpy(glob_script_mem.script_ram,str.c_str(), glob_script_mem.script_size);
|
||||||
|
|
||||||
#ifdef USE_24C256
|
#if defined(USE_24C256) && !defined(USE_SCRIPT_FATFS)
|
||||||
#ifndef USE_SCRIPT_FATFS
|
|
||||||
if (glob_script_mem.flags&1) {
|
if (glob_script_mem.flags&1) {
|
||||||
EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram);
|
EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_SCRIPT_FATFS
|
#if !defined(USE_24C256) && defined(USE_SCRIPT_FATFS)
|
||||||
if (glob_script_mem.flags&1) {
|
if (glob_script_mem.flags&1) {
|
||||||
SD.remove(FAT_SCRIPT_NAME);
|
FS_USED.remove(FAT_SCRIPT_NAME);
|
||||||
File file=SD.open(FAT_SCRIPT_NAME,FILE_WRITE);
|
File file=FS_USED.open(FAT_SCRIPT_NAME,FILE_WRITE);
|
||||||
file.write(glob_script_mem.script_ram,FAT_SCRIPT_SIZE);
|
file.write((const uint8_t*)glob_script_mem.script_ram,FAT_SCRIPT_SIZE);
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -4278,6 +4479,14 @@ void dateTime(uint16_t* date, uint16_t* time) {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef SUPPORT_MQTT_EVENT
|
#ifdef SUPPORT_MQTT_EVENT
|
||||||
|
|
||||||
|
#ifndef MQTT_EVENT_MSIZE
|
||||||
|
#define MQTT_EVENT_MSIZE 256
|
||||||
|
#endif
|
||||||
|
#ifndef MQTT_EVENT_JSIZE
|
||||||
|
#define MQTT_EVENT_JSIZE 400
|
||||||
|
#endif
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
/*
|
/*
|
||||||
* Script: Process received MQTT message.
|
* Script: Process received MQTT message.
|
||||||
@ -4292,8 +4501,8 @@ bool ScriptMqttData(void)
|
|||||||
{
|
{
|
||||||
bool serviced = false;
|
bool serviced = false;
|
||||||
//toLog(">>> 1");
|
//toLog(">>> 1");
|
||||||
toLog(XdrvMailbox.data);
|
//toLog(XdrvMailbox.data);
|
||||||
if (XdrvMailbox.data_len < 1 || XdrvMailbox.data_len > 256) {
|
if (XdrvMailbox.data_len < 1 || XdrvMailbox.data_len > MQTT_EVENT_MSIZE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String sTopic = XdrvMailbox.topic;
|
String sTopic = XdrvMailbox.topic;
|
||||||
@ -4313,7 +4522,7 @@ bool ScriptMqttData(void)
|
|||||||
if (event_item.Key.length() == 0) { //If did not specify Key
|
if (event_item.Key.length() == 0) { //If did not specify Key
|
||||||
value = sData;
|
value = sData;
|
||||||
} else { //If specified Key, need to parse Key/Value from JSON data
|
} else { //If specified Key, need to parse Key/Value from JSON data
|
||||||
StaticJsonBuffer<400> jsonBuf;
|
StaticJsonBuffer<MQTT_EVENT_JSIZE> jsonBuf;
|
||||||
JsonObject& jsonData = jsonBuf.parseObject(sData);
|
JsonObject& jsonData = jsonBuf.parseObject(sData);
|
||||||
String key1 = event_item.Key;
|
String key1 = event_item.Key;
|
||||||
String key2;
|
String key2;
|
||||||
@ -4557,7 +4766,7 @@ uint32_t cnt;
|
|||||||
nbuf[cnt]=0;
|
nbuf[cnt]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptWebShow(void) {
|
void ScriptWebShow(char mc) {
|
||||||
uint8_t web_script=Run_Scripter(">W",-2,0);
|
uint8_t web_script=Run_Scripter(">W",-2,0);
|
||||||
if (web_script==99) {
|
if (web_script==99) {
|
||||||
char line[128];
|
char line[128];
|
||||||
@ -4584,12 +4793,16 @@ void ScriptWebShow(void) {
|
|||||||
cp++;
|
cp++;
|
||||||
}
|
}
|
||||||
char *lin=line;
|
char *lin=line;
|
||||||
|
if (!mc && (*lin!='&')) {
|
||||||
|
|
||||||
if (*lin=='@') {
|
if (*lin=='@') {
|
||||||
lin++;
|
lin++;
|
||||||
optflg=1;
|
optflg=1;
|
||||||
} else {
|
} else {
|
||||||
optflg=0;
|
optflg=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// check for input elements
|
// check for input elements
|
||||||
if (!strncmp(lin,"sl(",3)) {
|
if (!strncmp(lin,"sl(",3)) {
|
||||||
// insert slider sl(min max var left mid right)
|
// insert slider sl(min max var left mid right)
|
||||||
@ -4749,6 +4962,12 @@ void ScriptWebShow(void) {
|
|||||||
WSContentSend_PD(PSTR("{s}%s{e}"),tmp);
|
WSContentSend_PD(PSTR("{s}%s{e}"),tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (*lin==mc) {
|
||||||
|
Replace_Cmd_Vars(lin+1,tmp,sizeof(tmp));
|
||||||
|
WSContentSend_PD(PSTR("%s"),tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (*lp==SCRIPT_EOL) {
|
if (*lp==SCRIPT_EOL) {
|
||||||
lp++;
|
lp++;
|
||||||
@ -4765,12 +4984,7 @@ void ScriptWebShow(void) {
|
|||||||
|
|
||||||
#ifdef USE_SENDMAIL
|
#ifdef USE_SENDMAIL
|
||||||
|
|
||||||
#ifdef ESP8266
|
void script_send_email_body(void(*func)(char *)) {
|
||||||
void script_send_email_body(BearSSL::WiFiClientSecure_light *client) {
|
|
||||||
#else
|
|
||||||
void script_send_email_body(WiFiClient *client) {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t msect=Run_Scripter(">m",-2,0);
|
uint8_t msect=Run_Scripter(">m",-2,0);
|
||||||
if (msect==99) {
|
if (msect==99) {
|
||||||
char line[128];
|
char line[128];
|
||||||
@ -4796,7 +5010,8 @@ uint8_t msect=Run_Scripter(">m",-2,0);
|
|||||||
cp++;
|
cp++;
|
||||||
}
|
}
|
||||||
Replace_Cmd_Vars(line,tmp,sizeof(tmp));
|
Replace_Cmd_Vars(line,tmp,sizeof(tmp));
|
||||||
client->println(tmp);
|
//client->println(tmp);
|
||||||
|
func(tmp);
|
||||||
}
|
}
|
||||||
if (*lp==SCRIPT_EOL) {
|
if (*lp==SCRIPT_EOL) {
|
||||||
lp++;
|
lp++;
|
||||||
@ -4807,7 +5022,8 @@ uint8_t msect=Run_Scripter(">m",-2,0);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
client->println("*");
|
//client->println("*");
|
||||||
|
func((char*)"*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -4868,14 +5084,8 @@ bool Xdrv10(uint8_t function)
|
|||||||
|
|
||||||
switch (function) {
|
switch (function) {
|
||||||
case FUNC_PRE_INIT:
|
case FUNC_PRE_INIT:
|
||||||
/*
|
|
||||||
#ifdef USE_WEBCAM
|
|
||||||
if (Settings.module==ESP32_CAM_AITHINKER) {
|
|
||||||
webcam_setup();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
// set defaults to rules memory
|
// set defaults to rules memory
|
||||||
|
//bitWrite(Settings.rule_enabled,0,0);
|
||||||
glob_script_mem.script_ram=Settings.rules[0];
|
glob_script_mem.script_ram=Settings.rules[0];
|
||||||
glob_script_mem.script_size=MAX_SCRIPT_SIZE;
|
glob_script_mem.script_size=MAX_SCRIPT_SIZE;
|
||||||
glob_script_mem.flags=0;
|
glob_script_mem.flags=0;
|
||||||
@ -4915,15 +5125,29 @@ bool Xdrv10(uint8_t function)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SCRIPT_FATFS
|
#ifdef USE_SCRIPT_FATFS
|
||||||
if (SD.begin(USE_SCRIPT_FATFS)) {
|
|
||||||
|
#ifdef USE_MMC
|
||||||
|
if (FS_USED.begin()) {
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) {
|
||||||
|
SPI.begin(Pin(GPIO_SPI_CLK),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_MOSI), -1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (FS_USED.begin(USE_SCRIPT_FATFS)) {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//FS_USED.dateTimeCallback(dateTime);
|
||||||
|
|
||||||
glob_script_mem.script_sd_found=1;
|
glob_script_mem.script_sd_found=1;
|
||||||
char *script;
|
char *script;
|
||||||
script=(char*)calloc(FAT_SCRIPT_SIZE+4,1);
|
script=(char*)calloc(FAT_SCRIPT_SIZE+4,1);
|
||||||
if (!script) break;
|
if (!script) break;
|
||||||
glob_script_mem.script_ram=script;
|
glob_script_mem.script_ram=script;
|
||||||
glob_script_mem.script_size=FAT_SCRIPT_SIZE;
|
glob_script_mem.script_size=FAT_SCRIPT_SIZE;
|
||||||
if (SD.exists(FAT_SCRIPT_NAME)) {
|
if (FS_USED.exists(FAT_SCRIPT_NAME)) {
|
||||||
File file=SD.open(FAT_SCRIPT_NAME,FILE_READ);
|
File file=FS_USED.open(FAT_SCRIPT_NAME,FILE_READ);
|
||||||
file.read((uint8_t*)script,FAT_SCRIPT_SIZE);
|
file.read((uint8_t*)script,FAT_SCRIPT_SIZE);
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
@ -4934,11 +5158,6 @@ bool Xdrv10(uint8_t function)
|
|||||||
|
|
||||||
glob_script_mem.flags=1;
|
glob_script_mem.flags=1;
|
||||||
|
|
||||||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
|
|
||||||
// for unkonwn reasons is not defined in 2.52
|
|
||||||
SdFile::dateTimeCallback(dateTime);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
glob_script_mem.script_sd_found=0;
|
glob_script_mem.script_sd_found=0;
|
||||||
}
|
}
|
||||||
@ -5001,6 +5220,10 @@ bool Xdrv10(uint8_t function)
|
|||||||
case FUNC_WEB_ADD_BUTTON:
|
case FUNC_WEB_ADD_BUTTON:
|
||||||
WSContentSend_P(HTTP_BTN_MENU_RULES);
|
WSContentSend_P(HTTP_BTN_MENU_RULES);
|
||||||
break;
|
break;
|
||||||
|
case FUNC_WEB_ADD_MAIN_BUTTON:
|
||||||
|
ScriptWebShow('&');
|
||||||
|
break;
|
||||||
|
|
||||||
case FUNC_WEB_ADD_HANDLER:
|
case FUNC_WEB_ADD_HANDLER:
|
||||||
Webserver->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration);
|
Webserver->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration);
|
||||||
Webserver->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration);
|
Webserver->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration);
|
||||||
@ -5028,7 +5251,7 @@ bool Xdrv10(uint8_t function)
|
|||||||
#ifdef USE_SCRIPT_WEB_DISPLAY
|
#ifdef USE_SCRIPT_WEB_DISPLAY
|
||||||
case FUNC_WEB_SENSOR:
|
case FUNC_WEB_SENSOR:
|
||||||
if (bitRead(Settings.rule_enabled, 0)) {
|
if (bitRead(Settings.rule_enabled, 0)) {
|
||||||
ScriptWebShow();
|
ScriptWebShow(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif //USE_SCRIPT_WEB_DISPLAY
|
#endif //USE_SCRIPT_WEB_DISPLAY
|
||||||
|
648
tasmota/xdrv_39_webcam.ino
Normal file
648
tasmota/xdrv_39_webcam.ino
Normal file
@ -0,0 +1,648 @@
|
|||||||
|
|
||||||
|
#if defined(ESP32) && defined(USE_WEBCAM)
|
||||||
|
|
||||||
|
#define XDRV_39 39
|
||||||
|
|
||||||
|
#define CAMERA_MODEL_AI_THINKER
|
||||||
|
|
||||||
|
//#define USE_TEMPLATE
|
||||||
|
|
||||||
|
#define WC_LOGLEVEL LOG_LEVEL_INFO
|
||||||
|
|
||||||
|
|
||||||
|
#define PWDN_GPIO_NUM 32
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 0
|
||||||
|
#define SIOD_GPIO_NUM 26
|
||||||
|
#define SIOC_GPIO_NUM 27
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 35
|
||||||
|
#define Y8_GPIO_NUM 34
|
||||||
|
#define Y7_GPIO_NUM 39
|
||||||
|
#define Y6_GPIO_NUM 36
|
||||||
|
#define Y5_GPIO_NUM 21
|
||||||
|
#define Y4_GPIO_NUM 19
|
||||||
|
#define Y3_GPIO_NUM 18
|
||||||
|
#define Y2_GPIO_NUM 5
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 23
|
||||||
|
#define PCLK_GPIO_NUM 22
|
||||||
|
|
||||||
|
|
||||||
|
#include "esp_camera.h"
|
||||||
|
#include "sensor.h"
|
||||||
|
|
||||||
|
uint8_t wc_up;
|
||||||
|
uint16_t wc_width;
|
||||||
|
uint16_t wc_height;
|
||||||
|
uint8_t wc_stream_active;
|
||||||
|
|
||||||
|
uint32_t wc_setup(int32_t fsiz) {
|
||||||
|
bool psram;
|
||||||
|
|
||||||
|
if (fsiz>10) fsiz=10;
|
||||||
|
|
||||||
|
wc_stream_active=0;
|
||||||
|
|
||||||
|
if (fsiz<0) {
|
||||||
|
esp_camera_deinit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wc_up) {
|
||||||
|
esp_camera_deinit();
|
||||||
|
//return wc_up;
|
||||||
|
}
|
||||||
|
|
||||||
|
//esp_log_level_set("*", ESP_LOG_VERBOSE);
|
||||||
|
|
||||||
|
camera_config_t config;
|
||||||
|
config.ledc_channel = LEDC_CHANNEL_0;
|
||||||
|
config.ledc_timer = LEDC_TIMER_0;
|
||||||
|
config.xclk_freq_hz = 20000000;
|
||||||
|
config.pixel_format = PIXFORMAT_JPEG;
|
||||||
|
// config.pixel_format = PIXFORMAT_GRAYSCALE;
|
||||||
|
// config.pixel_format = PIXFORMAT_RGB565;
|
||||||
|
|
||||||
|
#ifndef USE_TEMPLATE
|
||||||
|
|
||||||
|
config.pin_d0 = Y2_GPIO_NUM;
|
||||||
|
config.pin_d1 = Y3_GPIO_NUM;
|
||||||
|
config.pin_d2 = Y4_GPIO_NUM;
|
||||||
|
config.pin_d3 = Y5_GPIO_NUM;
|
||||||
|
config.pin_d4 = Y6_GPIO_NUM;
|
||||||
|
config.pin_d5 = Y7_GPIO_NUM;
|
||||||
|
config.pin_d6 = Y8_GPIO_NUM;
|
||||||
|
config.pin_d7 = Y9_GPIO_NUM;
|
||||||
|
config.pin_xclk = XCLK_GPIO_NUM;
|
||||||
|
config.pin_pclk = PCLK_GPIO_NUM;
|
||||||
|
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||||
|
config.pin_href = HREF_GPIO_NUM;
|
||||||
|
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||||
|
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||||
|
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||||
|
config.pin_reset = RESET_GPIO_NUM;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (PinUsed(GPIO_WEBCAM_Y2_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y3_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y4_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y5_GPIO_NUM)\
|
||||||
|
&& PinUsed(GPIO_WEBCAM_Y6_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y7_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y8_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y9_GPIO_NUM)\
|
||||||
|
&& PinUsed(GPIO_WEBCAM_XCLK_GPIO_NUM) && PinUsed(GPIO_WEBCAM_PCLK_GPIO_NUM) && PinUsed(GPIO_WEBCAM_VSYNC_GPIO_NUM) && PinUsed(GPIO_WEBCAM_HREF_GPIO_NUM)\
|
||||||
|
&& PinUsed(GPIO_WEBCAM_SIOD_GPIO_NUM) && PinUsed(GPIO_WEBCAM_SIOC_GPIO_NUM)) {
|
||||||
|
|
||||||
|
config.pin_d0 = Pin(GPIO_WEBCAM_Y2_GPIO_NUM); //Y2_GPIO_NUM;
|
||||||
|
config.pin_d1 = Pin(GPIO_WEBCAM_Y3_GPIO_NUM); //Y3_GPIO_NUM;
|
||||||
|
config.pin_d2 = Pin(GPIO_WEBCAM_Y4_GPIO_NUM); //Y4_GPIO_NUM;
|
||||||
|
config.pin_d3 = Pin(GPIO_WEBCAM_Y5_GPIO_NUM); //Y5_GPIO_NUM;
|
||||||
|
config.pin_d4 = Pin(GPIO_WEBCAM_Y6_GPIO_NUM); //Y6_GPIO_NUM;
|
||||||
|
config.pin_d5 = Pin(GPIO_WEBCAM_Y7_GPIO_NUM); //Y7_GPIO_NUM;
|
||||||
|
config.pin_d6 = Pin(GPIO_WEBCAM_Y8_GPIO_NUM); //Y8_GPIO_NUM;
|
||||||
|
config.pin_d7 = Pin(GPIO_WEBCAM_Y9_GPIO_NUM); //Y9_GPIO_NUM;
|
||||||
|
config.pin_xclk = Pin(GPIO_WEBCAM_XCLK_GPIO_NUM); //XCLK_GPIO_NUM;
|
||||||
|
config.pin_pclk = Pin(GPIO_WEBCAM_PCLK_GPIO_NUM); //PCLK_GPIO_NUM;
|
||||||
|
config.pin_vsync = Pin(GPIO_WEBCAM_VSYNC_GPIO_NUM); //VSYNC_GPIO_NUM;
|
||||||
|
config.pin_href = Pin(GPIO_WEBCAM_HREF_GPIO_NUM); //HREF_GPIO_NUM;
|
||||||
|
config.pin_sscb_sda = Pin(GPIO_WEBCAM_SIOD_GPIO_NUM); //SIOD_GPIO_NUM;
|
||||||
|
config.pin_sscb_scl = Pin(GPIO_WEBCAM_SIOC_GPIO_NUM); //SIOC_GPIO_NUM;
|
||||||
|
|
||||||
|
int16_t xpin;
|
||||||
|
xpin=Pin(GPIO_WEBCAM_PWDN_GPIO_NUM);
|
||||||
|
if (xpin==99) xpin=-1;
|
||||||
|
config.pin_pwdn = xpin; //PWDN_GPIO_NUM;
|
||||||
|
xpin=Pin(GPIO_WEBCAM_RESET_GPIO_NUM);
|
||||||
|
if (xpin==99) xpin=-1;
|
||||||
|
config.pin_reset = xpin; //RESET_GPIO_NUM;
|
||||||
|
} else {
|
||||||
|
// defaults to AI THINKER
|
||||||
|
config.pin_d0 = Y2_GPIO_NUM;
|
||||||
|
config.pin_d1 = Y3_GPIO_NUM;
|
||||||
|
config.pin_d2 = Y4_GPIO_NUM;
|
||||||
|
config.pin_d3 = Y5_GPIO_NUM;
|
||||||
|
config.pin_d4 = Y6_GPIO_NUM;
|
||||||
|
config.pin_d5 = Y7_GPIO_NUM;
|
||||||
|
config.pin_d6 = Y8_GPIO_NUM;
|
||||||
|
config.pin_d7 = Y9_GPIO_NUM;
|
||||||
|
config.pin_xclk = XCLK_GPIO_NUM;
|
||||||
|
config.pin_pclk = PCLK_GPIO_NUM;
|
||||||
|
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||||
|
config.pin_href = HREF_GPIO_NUM;
|
||||||
|
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||||
|
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||||
|
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||||
|
config.pin_reset = RESET_GPIO_NUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//ESP.getPsramSize()
|
||||||
|
|
||||||
|
//esp_log_level_set("*", ESP_LOG_INFO);
|
||||||
|
|
||||||
|
|
||||||
|
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
|
||||||
|
// for larger pre-allocated frame buffer.
|
||||||
|
|
||||||
|
psram=psramFound();
|
||||||
|
if (psram) {
|
||||||
|
config.frame_size = FRAMESIZE_UXGA;
|
||||||
|
config.jpeg_quality = 10;
|
||||||
|
config.fb_count = 2;
|
||||||
|
AddLog_P(WC_LOGLEVEL,"PSRAM found!");
|
||||||
|
} else {
|
||||||
|
config.frame_size = FRAMESIZE_VGA;
|
||||||
|
config.jpeg_quality = 12;
|
||||||
|
config.fb_count = 1;
|
||||||
|
AddLog_P(WC_LOGLEVEL,"PSRAM not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// stupid workaround camera diver eats up static ram should prefer PSRAM
|
||||||
|
// so we steal static ram to force driver to alloc PSRAM
|
||||||
|
//ESP.getMaxAllocHeap()
|
||||||
|
|
||||||
|
// void *x=malloc(70000);
|
||||||
|
void *x=0;
|
||||||
|
|
||||||
|
esp_err_t err = esp_camera_init(&config);
|
||||||
|
|
||||||
|
if (x) free(x);
|
||||||
|
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
AddLog_P2(WC_LOGLEVEL,"Camera init failed with error 0x%x", err);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor_t * wc_s = esp_camera_sensor_get();
|
||||||
|
// initial sensors are flipped vertically and colors are a bit saturated
|
||||||
|
if (wc_s->id.PID == OV3660_PID) {
|
||||||
|
wc_s->set_vflip(wc_s, 1); // flip it back
|
||||||
|
wc_s->set_brightness(wc_s, 1); // up the brightness just a bit
|
||||||
|
wc_s->set_saturation(wc_s, -2); // lower the saturation
|
||||||
|
}
|
||||||
|
// drop down frame size for higher initial frame rate
|
||||||
|
wc_s->set_framesize(wc_s, (framesize_t)fsiz);
|
||||||
|
|
||||||
|
camera_fb_t *wc_fb = esp_camera_fb_get();
|
||||||
|
wc_width=wc_fb->width;
|
||||||
|
wc_height=wc_fb->height;
|
||||||
|
esp_camera_fb_return(wc_fb);
|
||||||
|
|
||||||
|
AddLog_P(WC_LOGLEVEL,"Camera successfully initialized!");
|
||||||
|
|
||||||
|
wc_up=1;
|
||||||
|
|
||||||
|
if (psram) {
|
||||||
|
wc_up=2;
|
||||||
|
}
|
||||||
|
return wc_up;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t wc_set_options(uint32_t sel,int32_t value) {
|
||||||
|
int32_t res=0;
|
||||||
|
sensor_t *s = esp_camera_sensor_get();
|
||||||
|
if (!s) return -99;
|
||||||
|
|
||||||
|
switch (sel) {
|
||||||
|
case 0:
|
||||||
|
if (value>=0) s->set_framesize(s,(framesize_t)value);
|
||||||
|
res = s->status.framesize;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (value>=0) s->set_special_effect(s,value);
|
||||||
|
res = s->status.special_effect;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (value>=0) s->set_vflip(s,value);
|
||||||
|
res = s->status.vflip;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (value>=0) s->set_hmirror(s,value);
|
||||||
|
res = s->status.hmirror;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (value>=-4) s->set_contrast(s,value);
|
||||||
|
res = s->status.contrast;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (value>=-4) s->set_brightness(s,value);
|
||||||
|
res = s->status.brightness;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if (value>=-4) s->set_saturation(s,value);
|
||||||
|
res = s->status.saturation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t wc_get_width(void) {
|
||||||
|
camera_fb_t *wc_fb = esp_camera_fb_get();
|
||||||
|
if (!wc_fb) return 0;
|
||||||
|
wc_width=wc_fb->width;
|
||||||
|
esp_camera_fb_return(wc_fb);
|
||||||
|
return wc_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t wc_get_height(void) {
|
||||||
|
camera_fb_t *wc_fb = esp_camera_fb_get();
|
||||||
|
if (!wc_fb) return 0;
|
||||||
|
wc_height=wc_fb->height;
|
||||||
|
esp_camera_fb_return(wc_fb);
|
||||||
|
return wc_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef MAX_PICSTORE
|
||||||
|
#define MAX_PICSTORE 4
|
||||||
|
#endif
|
||||||
|
struct PICSTORE {
|
||||||
|
uint8_t *buff;
|
||||||
|
uint32_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PICSTORE picstore[MAX_PICSTORE];
|
||||||
|
|
||||||
|
#ifdef COPYFRAME
|
||||||
|
struct PICSTORE tmp_picstore;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t get_picstore(int32_t num, uint8_t **buff) {
|
||||||
|
if (num<0) return MAX_PICSTORE;
|
||||||
|
*buff=picstore[num].buff;
|
||||||
|
return picstore[num].len;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t wc_get_jpeg(uint8_t **buff) {
|
||||||
|
size_t _jpg_buf_len = 0;
|
||||||
|
uint8_t * _jpg_buf = NULL;
|
||||||
|
camera_fb_t *wc_fb;
|
||||||
|
wc_fb = esp_camera_fb_get();
|
||||||
|
if (!wc_fb) return 0;
|
||||||
|
if (wc_fb->format!=PIXFORMAT_JPEG) {
|
||||||
|
bool jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len);
|
||||||
|
if (!jpeg_converted){
|
||||||
|
_jpg_buf_len = wc_fb->len;
|
||||||
|
_jpg_buf = wc_fb->buf;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_jpg_buf_len = wc_fb->len;
|
||||||
|
_jpg_buf = wc_fb->buf;
|
||||||
|
}
|
||||||
|
esp_camera_fb_return(wc_fb);
|
||||||
|
*buff=_jpg_buf;
|
||||||
|
return _jpg_buf_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t wc_get_frame(int32_t bnum) {
|
||||||
|
size_t _jpg_buf_len = 0;
|
||||||
|
uint8_t * _jpg_buf = NULL;
|
||||||
|
camera_fb_t *wc_fb=0;
|
||||||
|
bool jpeg_converted=false;
|
||||||
|
|
||||||
|
if (bnum<0) {
|
||||||
|
if (bnum<-MAX_PICSTORE) bnum=-1;
|
||||||
|
bnum=-bnum;
|
||||||
|
bnum--;
|
||||||
|
if (picstore[bnum].buff) free(picstore[bnum].buff);
|
||||||
|
picstore[bnum].len=0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef COPYFRAME
|
||||||
|
if (bnum&0x10) {
|
||||||
|
bnum&=0xf;
|
||||||
|
_jpg_buf=tmp_picstore.buff;
|
||||||
|
_jpg_buf_len=tmp_picstore.len;
|
||||||
|
if (!_jpg_buf_len) return 0;
|
||||||
|
goto pcopy;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wc_fb = esp_camera_fb_get();
|
||||||
|
if (!wc_fb) {
|
||||||
|
AddLog_P(WC_LOGLEVEL, "cant get frame");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!bnum) {
|
||||||
|
wc_width = wc_fb->width;
|
||||||
|
wc_height = wc_fb->height;
|
||||||
|
esp_camera_fb_return(wc_fb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wc_fb->format!=PIXFORMAT_JPEG) {
|
||||||
|
jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len);
|
||||||
|
if (!jpeg_converted){
|
||||||
|
//Serial.println("JPEG compression failed");
|
||||||
|
_jpg_buf_len = wc_fb->len;
|
||||||
|
_jpg_buf = wc_fb->buf;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_jpg_buf_len = wc_fb->len;
|
||||||
|
_jpg_buf = wc_fb->buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcopy:
|
||||||
|
if (bnum<1 || bnum>MAX_PICSTORE) bnum=1;
|
||||||
|
bnum--;
|
||||||
|
if (picstore[bnum].buff) free(picstore[bnum].buff);
|
||||||
|
picstore[bnum].buff = (uint8_t *)heap_caps_malloc(_jpg_buf_len+4,MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
|
if (picstore[bnum].buff) {
|
||||||
|
memcpy(picstore[bnum].buff,_jpg_buf,_jpg_buf_len);
|
||||||
|
picstore[bnum].len=_jpg_buf_len;
|
||||||
|
} else {
|
||||||
|
AddLog_P(WC_LOGLEVEL, "cant allocate picstore");
|
||||||
|
picstore[bnum].len=0;
|
||||||
|
}
|
||||||
|
if (wc_fb) esp_camera_fb_return(wc_fb);
|
||||||
|
if (jpeg_converted) free(_jpg_buf);
|
||||||
|
if (!picstore[bnum].buff) return 0;
|
||||||
|
return _jpg_buf_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HttpCheckPriviledgedAccess(bool);
|
||||||
|
extern ESP8266WebServer *Webserver;
|
||||||
|
|
||||||
|
void HandleImage(void) {
|
||||||
|
if (!HttpCheckPriviledgedAccess(true)) { return; }
|
||||||
|
|
||||||
|
uint32_t bnum = Webserver->arg(F("p")).toInt();
|
||||||
|
if (bnum<0 || bnum>MAX_PICSTORE) bnum=1;
|
||||||
|
WiFiClient client = Webserver->client();
|
||||||
|
String response = "HTTP/1.1 200 OK\r\n";
|
||||||
|
response += "Content-disposition: inline; filename=cap.jpg\r\n";
|
||||||
|
response += "Content-type: image/jpeg\r\n\r\n";
|
||||||
|
Webserver->sendContent(response);
|
||||||
|
|
||||||
|
if (!bnum) {
|
||||||
|
uint8_t *buff;
|
||||||
|
uint32_t len;
|
||||||
|
len=wc_get_jpeg(&buff);
|
||||||
|
if (len) {
|
||||||
|
client.write(buff,len);
|
||||||
|
free(buff);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bnum--;
|
||||||
|
if (!picstore[bnum].len) {
|
||||||
|
AddLog_P2(WC_LOGLEVEL, PSTR("no image #: %d"), bnum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client.write((char *)picstore[bnum].buff, picstore[bnum].len);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddLog_P2(WC_LOGLEVEL, PSTR("sending image #: %d"), bnum+1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP8266WebServer *CamServer;
|
||||||
|
#define BOUNDARY "e8b8c539-047d-4777-a985-fbba6edff11e"
|
||||||
|
|
||||||
|
WiFiClient client;
|
||||||
|
|
||||||
|
void handleMjpeg(void) {
|
||||||
|
AddLog_P(WC_LOGLEVEL, "handle camserver");
|
||||||
|
//if (!wc_stream_active) {
|
||||||
|
wc_stream_active=1;
|
||||||
|
client = CamServer->client();
|
||||||
|
AddLog_P(WC_LOGLEVEL, "create client");
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void handleMjpeg_task(void) {
|
||||||
|
camera_fb_t *wc_fb;
|
||||||
|
size_t _jpg_buf_len = 0;
|
||||||
|
uint8_t * _jpg_buf = NULL;
|
||||||
|
|
||||||
|
//WiFiClient client = CamServer->client();
|
||||||
|
uint32_t tlen;
|
||||||
|
bool jpeg_converted=false;
|
||||||
|
|
||||||
|
if (!client.connected()) {
|
||||||
|
wc_stream_active=0;
|
||||||
|
AddLog_P(WC_LOGLEVEL,"client fail");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wc_stream_active==1) {
|
||||||
|
client.flush();
|
||||||
|
client.setTimeout(3);
|
||||||
|
AddLog_P(WC_LOGLEVEL, "start stream");
|
||||||
|
client.print("HTTP/1.1 200 OK\r\n"
|
||||||
|
"Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY "\r\n"
|
||||||
|
"\r\n");
|
||||||
|
wc_stream_active=2;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
wc_fb = esp_camera_fb_get();
|
||||||
|
if (!wc_fb) {
|
||||||
|
wc_stream_active=0;
|
||||||
|
AddLog_P(WC_LOGLEVEL, "frame fail");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wc_fb->format!=PIXFORMAT_JPEG) {
|
||||||
|
jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len);
|
||||||
|
if (!jpeg_converted){
|
||||||
|
AddLog_P(WC_LOGLEVEL, "JPEG compression failed");
|
||||||
|
_jpg_buf_len = wc_fb->len;
|
||||||
|
_jpg_buf = wc_fb->buf;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_jpg_buf_len = wc_fb->len;
|
||||||
|
_jpg_buf = wc_fb->buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.printf("Content-Type: image/jpeg\r\n"
|
||||||
|
"Content-Length: %d\r\n"
|
||||||
|
"\r\n", static_cast<int>(_jpg_buf_len));
|
||||||
|
tlen=client.write(_jpg_buf, _jpg_buf_len);
|
||||||
|
/*
|
||||||
|
if (tlen!=_jpg_buf_len) {
|
||||||
|
esp_camera_fb_return(wc_fb);
|
||||||
|
wc_stream_active=0;
|
||||||
|
AddLog_P(WC_LOGLEVEL, "send fail");
|
||||||
|
}*/
|
||||||
|
client.print("\r\n--" BOUNDARY "\r\n");
|
||||||
|
|
||||||
|
#ifdef COPYFRAME
|
||||||
|
if (tmp_picstore.buff) free(tmp_picstore.buff);
|
||||||
|
tmp_picstore.buff = (uint8_t *)heap_caps_malloc(_jpg_buf_len+4,MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
|
if (tmp_picstore.buff) {
|
||||||
|
memcpy(tmp_picstore.buff,_jpg_buf,_jpg_buf_len);
|
||||||
|
tmp_picstore.len=_jpg_buf_len;
|
||||||
|
} else {
|
||||||
|
tmp_picstore.len=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (jpeg_converted) free(_jpg_buf);
|
||||||
|
esp_camera_fb_return(wc_fb);
|
||||||
|
//AddLog_P(WC_LOGLEVEL, "send frame");
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!wc_stream_active) {
|
||||||
|
AddLog_P(WC_LOGLEVEL, "stream exit");
|
||||||
|
client.flush();
|
||||||
|
client.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CamHandleRoot(void) {
|
||||||
|
//CamServer->redirect("http://" + String(ip) + ":81/cam.mjpeg");
|
||||||
|
CamServer->sendHeader("Location", WiFi.localIP().toString() + ":81/cam.mjpeg");
|
||||||
|
CamServer->send(302, "", "");
|
||||||
|
Serial.printf("WC root called");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t motion_detect;
|
||||||
|
uint32_t motion_ltime;
|
||||||
|
uint32_t motion_trigger;
|
||||||
|
uint32_t motion_brightness;
|
||||||
|
uint8_t *last_motion_buffer;
|
||||||
|
|
||||||
|
uint32_t wc_set_motion_detect(int32_t value) {
|
||||||
|
if (value>=0) motion_detect=value;
|
||||||
|
if (value==-1) {
|
||||||
|
return motion_trigger;
|
||||||
|
} else {
|
||||||
|
return motion_brightness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional motion detector
|
||||||
|
void detect_motion(void) {
|
||||||
|
camera_fb_t *wc_fb;
|
||||||
|
uint8_t *out_buf=0;
|
||||||
|
|
||||||
|
if ((millis()-motion_ltime)>motion_detect) {
|
||||||
|
motion_ltime=millis();
|
||||||
|
wc_fb = esp_camera_fb_get();
|
||||||
|
if (!wc_fb) return;
|
||||||
|
|
||||||
|
if (!last_motion_buffer) {
|
||||||
|
last_motion_buffer=(uint8_t *)heap_caps_malloc((wc_fb->width*wc_fb->height)+4,MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
|
}
|
||||||
|
if (last_motion_buffer) {
|
||||||
|
if (wc_fb->format==PIXFORMAT_JPEG) {
|
||||||
|
out_buf=(uint8_t *)heap_caps_malloc((wc_fb->width*wc_fb->height*3)+4,MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
|
if (out_buf) {
|
||||||
|
fmt2rgb888(wc_fb->buf, wc_fb->len, wc_fb->format, out_buf);
|
||||||
|
uint32_t x,y;
|
||||||
|
uint8_t *pxi=out_buf;
|
||||||
|
uint8_t *pxr=last_motion_buffer;
|
||||||
|
// convert to bw
|
||||||
|
uint64_t accu=0;
|
||||||
|
uint64_t bright=0;
|
||||||
|
for (y=0;y<wc_fb->height;y++) {
|
||||||
|
for (x=0;x<wc_fb->width;x++) {
|
||||||
|
int32_t gray=(pxi[0]+pxi[1]+pxi[2])/3;
|
||||||
|
int32_t lgray=pxr[0];
|
||||||
|
pxr[0]=gray;
|
||||||
|
pxi+=3;
|
||||||
|
pxr++;
|
||||||
|
accu+=abs(gray-lgray);
|
||||||
|
bright+=gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
motion_trigger=accu/((wc_fb->height*wc_fb->width)/100);
|
||||||
|
motion_brightness=bright/((wc_fb->height*wc_fb->width)/100);
|
||||||
|
free(out_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
esp_camera_fb_return(wc_fb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t wc_set_streamserver(uint32_t flag) {
|
||||||
|
|
||||||
|
if (global_state.wifi_down) return 0;
|
||||||
|
|
||||||
|
wc_stream_active=0;
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
if (!CamServer) {
|
||||||
|
CamServer = new ESP8266WebServer(81);
|
||||||
|
CamServer->on("/", CamHandleRoot);
|
||||||
|
CamServer->on("/cam.mjpeg", handleMjpeg);
|
||||||
|
CamServer->on("/cam.jpg", handleMjpeg);
|
||||||
|
CamServer->on("/stream", handleMjpeg);
|
||||||
|
AddLog_P(WC_LOGLEVEL, "cam stream init");
|
||||||
|
CamServer->begin();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (CamServer) {
|
||||||
|
CamServer->stop();
|
||||||
|
delete CamServer;
|
||||||
|
CamServer=NULL;
|
||||||
|
AddLog_P(WC_LOGLEVEL, "cam stream exit");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wc_loop(void) {
|
||||||
|
if (CamServer) CamServer->handleClient();
|
||||||
|
if (wc_stream_active) handleMjpeg_task();
|
||||||
|
if (motion_detect) detect_motion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wc_pic_setup(void) {
|
||||||
|
Webserver->on("/wc.jpg", HandleImage);
|
||||||
|
Webserver->on("/wc.mjpeg", HandleImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
typedef enum {
|
||||||
|
// FRAMESIZE_96x96, // 96x96
|
||||||
|
FRAMESIZE_QQVGA, // 160x120 0
|
||||||
|
FRAMESIZE_QQVGA2, // 128x160 1
|
||||||
|
FRAMESIZE_QCIF, // 176x144 2
|
||||||
|
FRAMESIZE_HQVGA, // 240x176 3
|
||||||
|
|
||||||
|
// FRAMESIZE_240x240, // 240x240 3
|
||||||
|
|
||||||
|
FRAMESIZE_QVGA, // 320x240 4
|
||||||
|
FRAMESIZE_CIF, // 400x296 5
|
||||||
|
FRAMESIZE_VGA, // 640x480 6
|
||||||
|
FRAMESIZE_SVGA, // 800x600 7
|
||||||
|
FRAMESIZE_XGA, // 1024x768 8
|
||||||
|
FRAMESIZE_SXGA, // 1280x1024 9
|
||||||
|
FRAMESIZE_UXGA, // 1600x1200 10
|
||||||
|
|
||||||
|
|
||||||
|
FRAMESIZE_QXGA, // 2048*1536
|
||||||
|
FRAMESIZE_INVALID
|
||||||
|
} framesize_t;
|
||||||
|
|
||||||
|
flash led = gpio4
|
||||||
|
red led = gpio 33
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Interface
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
bool Xdrv39(uint8_t function) {
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
switch (function) {
|
||||||
|
case FUNC_LOOP:
|
||||||
|
wc_loop();
|
||||||
|
break;
|
||||||
|
case FUNC_WEB_ADD_HANDLER:
|
||||||
|
wc_pic_setup();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user