mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Merge branch 'pre-release-12.0'
This commit is contained in:
commit
dc1605f96a
2
.gitpod.Dockerfile
vendored
2
.gitpod.Dockerfile
vendored
@ -1,5 +1,3 @@
|
||||
FROM gitpod/workspace-full
|
||||
|
||||
USER gitpod
|
||||
|
||||
RUN pip3 install -U platformio
|
||||
|
@ -1,6 +1,5 @@
|
||||
tasks:
|
||||
- before: platformio upgrade
|
||||
- command: platformio run -e tasmota
|
||||
- command: pip3 install -U platformio && platformio run -e tasmota
|
||||
|
||||
image:
|
||||
file: .gitpod.Dockerfile
|
||||
|
15
CHANGELOG.md
15
CHANGELOG.md
@ -2,6 +2,21 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [Released]
|
||||
## [12.0.2] 20220620
|
||||
- Release Paul
|
||||
|
||||
## [12.0.1.2]
|
||||
### Added
|
||||
- Command ``DnsTimeout 100..20000`` to change default DNS timeout from 1000 msec blocking if no DNS server found
|
||||
|
||||
### Fixed
|
||||
- MQTT rc -4 connections regression from v12.0.0 (#15809)
|
||||
|
||||
## [12.0.1] 20220617
|
||||
- Release Paul
|
||||
|
||||
### Fixed
|
||||
- Resolving NTP and/or MQTT server names regression from v12.0.0 (#15816)
|
||||
|
||||
## [12.0.1] 20220617
|
||||
- Release Paul
|
||||
|
@ -72,7 +72,7 @@ Latest released binaries can be downloaded from
|
||||
- http://ota.tasmota.com/tasmota/release
|
||||
|
||||
Historical binaries can be downloaded from
|
||||
- http://ota.tasmota.com/tasmota/release-12.0.1
|
||||
- http://ota.tasmota.com/tasmota/release-12.0.2
|
||||
|
||||
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
|
||||
|
||||
@ -97,7 +97,7 @@ Latest released binaries can be downloaded from
|
||||
- http://ota.tasmota.com/tasmota32/release
|
||||
|
||||
Historical binaries can be downloaded from
|
||||
- http://ota.tasmota.com/tasmota32/release-12.0.1
|
||||
- http://ota.tasmota.com/tasmota32/release-12.0.2
|
||||
|
||||
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota32/release/tasmota32.bin``
|
||||
|
||||
@ -107,12 +107,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
||||
|
||||
[Complete list](BUILDS.md) of available feature and sensors.
|
||||
|
||||
## Changelog v12.0.1 Paul
|
||||
## Changelog v12.0.2 Paul
|
||||
### Added
|
||||
- Command ``SetOption139 0/1`` to switch between pressure unit "mmHg" (0) or "inHg" (1) when ``SO24 1`` [#15350](https://github.com/arendst/Tasmota/issues/15350)
|
||||
- Command ``SetOption140 0/1`` to switch between MQTT Clean Session (0) or Persistent Session (1) [#15530](https://github.com/arendst/Tasmota/issues/15530)
|
||||
- Command ``SetOption141 1`` to disable display of module name in GUI header
|
||||
- Command ``SetOption142 1`` to wait 1 second for wifi connection solving some FRITZ!Box modem issues [#14985](https://github.com/arendst/Tasmota/issues/14985)
|
||||
- Command ``DnsTimeout 100..20000`` to change default DNS timeout from 1000 msec blocking if no DNS server found
|
||||
- Command ``EnergyExportActive<phase>`` to (p)reset energy export active for supported devices. Currently ADE7880 only [#13515](https://github.com/arendst/Tasmota/issues/13515)
|
||||
- Command ``IfxRp ""|<policy>`` adds optional InfluxDb Retention Policy [#15513](https://github.com/arendst/Tasmota/issues/15513)
|
||||
- Command ``SspmDisplay 2`` to display Sonoff SPM energy data in GUI for user tab-selected relay modules [#13447](https://github.com/arendst/Tasmota/issues/13447)
|
||||
@ -144,6 +145,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
||||
- Possible pin output toggle after power on [#15630](https://github.com/arendst/Tasmota/issues/15630)
|
||||
- SHT1X driver hangs and wrong values on ESP32 [#15790](https://github.com/arendst/Tasmota/issues/15790)
|
||||
- Resolving NTP and/or MQTT server names regression from v12.0.0 [#15816](https://github.com/arendst/Tasmota/issues/15816)
|
||||
- MQTT rc -4 connection regression from v12.0.0 [#15809](https://github.com/arendst/Tasmota/issues/15809)
|
||||
- ESP32 Arduino Core WiFi timeout is changed from msec to seconds
|
||||
|
||||
### Removed
|
||||
|
7
lib/default/DnsClient/library.properties
Normal file
7
lib/default/DnsClient/library.properties
Normal file
@ -0,0 +1,7 @@
|
||||
name=DnsClient
|
||||
version=1.0
|
||||
author=MCQN Ltd, Theo Arends
|
||||
maintainer=Theo
|
||||
sentence=Dns client allowing timeout selection.
|
||||
paragraph=This class uses WifiUdp.
|
||||
architectures=esp8266,esp32
|
334
lib/default/DnsClient/src/DnsClient.cpp
Normal file
334
lib/default/DnsClient/src/DnsClient.cpp
Normal file
@ -0,0 +1,334 @@
|
||||
/*
|
||||
DnsClient.cpp - DNS client for Arduino
|
||||
|
||||
SPDX-FileCopyrightText: 2009-2010 MCQN Ltd. and Theo Arends
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
// Arduino DNS client for WizNet5100-based Ethernet shield
|
||||
// (c) Copyright 2009-2010 MCQN Ltd.
|
||||
// Released under Apache License, version 2.0
|
||||
|
||||
#include "DnsClient.h"
|
||||
|
||||
// Various flags and header field values for a DNS message
|
||||
#define UDP_HEADER_SIZE 8
|
||||
#define DNS_HEADER_SIZE 12
|
||||
#define TTL_SIZE 4
|
||||
#define QUERY_FLAG (0)
|
||||
#define RESPONSE_FLAG (1<<15)
|
||||
#define QUERY_RESPONSE_MASK (1<<15)
|
||||
#define OPCODE_STANDARD_QUERY (0)
|
||||
#define OPCODE_INVERSE_QUERY (1<<11)
|
||||
#define OPCODE_STATUS_REQUEST (2<<11)
|
||||
#define OPCODE_MASK (15<<11)
|
||||
#define AUTHORITATIVE_FLAG (1<<10)
|
||||
#define TRUNCATION_FLAG (1<<9)
|
||||
#define RECURSION_DESIRED_FLAG (1<<8)
|
||||
#define RECURSION_AVAILABLE_FLAG (1<<7)
|
||||
#define RESP_NO_ERROR (0)
|
||||
#define RESP_FORMAT_ERROR (1)
|
||||
#define RESP_SERVER_FAILURE (2)
|
||||
#define RESP_NAME_ERROR (3)
|
||||
#define RESP_NOT_IMPLEMENTED (4)
|
||||
#define RESP_REFUSED (5)
|
||||
#define RESP_MASK (15)
|
||||
#define TYPE_A (0x0001)
|
||||
#define CLASS_IN (0x0001)
|
||||
#define LABEL_COMPRESSION_MASK (0xC0)
|
||||
// Port number that DNS servers listen on
|
||||
#define DNS_PORT 53
|
||||
|
||||
// Possible return codes from ProcessResponse
|
||||
#define SUCCESS 1
|
||||
#define TIMED_OUT -1
|
||||
#define INVALID_SERVER -2
|
||||
#define TRUNCATED -3
|
||||
#define INVALID_RESPONSE -4
|
||||
|
||||
#ifndef htons
|
||||
#define htons(x) ( ((x)<< 8 & 0xFF00) | ((x)>> 8 & 0x00FF) )
|
||||
#endif
|
||||
|
||||
void DNSClient::begin(const IPAddress& aDNSServer) {
|
||||
iDNSServer = aDNSServer;
|
||||
iRequestId = 0;
|
||||
}
|
||||
|
||||
void DNSClient::setTimeout(uint32_t aTimeout) {
|
||||
iTimeout = aTimeout;
|
||||
}
|
||||
|
||||
int DNSClient::getHostByName(const char* aHostname, IPAddress& aResult) {
|
||||
// See if it's a numeric IP address
|
||||
if (aResult.fromString(aHostname)) {
|
||||
// It is, our work here is done
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Check we've got a valid DNS server to use
|
||||
if ((0xFFFFFFFF == (uint32_t)iDNSServer) || (0 == (uint32_t)iDNSServer)) {
|
||||
return INVALID_SERVER;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
// Find a socket to use
|
||||
if (iUdp.begin(1024+(millis() & 0xF)) == 1) {
|
||||
// Try up to three times
|
||||
int retries = 0;
|
||||
// while ((retries < 3) && (ret <= 0)) {
|
||||
// Send DNS request
|
||||
ret = iUdp.beginPacket(iDNSServer, DNS_PORT);
|
||||
if (ret != 0) {
|
||||
// Now output the request data
|
||||
ret = BuildRequest(aHostname);
|
||||
if (ret != 0) {
|
||||
// And finally send the request
|
||||
ret = iUdp.endPacket();
|
||||
if (ret != 0) {
|
||||
// Now wait for a response
|
||||
int wait_retries = 0;
|
||||
ret = TIMED_OUT;
|
||||
while ((wait_retries < 3) && (ret == TIMED_OUT)) {
|
||||
ret = ProcessResponse(iTimeout, aResult);
|
||||
wait_retries++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
retries++;
|
||||
// }
|
||||
// We're done with the socket now
|
||||
iUdp.stop();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DNSClient::BuildRequest(const char* aName) {
|
||||
// Build header
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
// | ID |
|
||||
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
// |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
|
||||
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
// | QDCOUNT |
|
||||
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
// | ANCOUNT |
|
||||
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
// | NSCOUNT |
|
||||
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
// | ARCOUNT |
|
||||
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
// As we only support one request at a time at present, we can simplify
|
||||
// some of this header
|
||||
iRequestId = millis(); // generate a random ID
|
||||
uint16_t twoByteBuffer;
|
||||
|
||||
// FIXME We should also check that there's enough space available to write to, rather
|
||||
// FIXME than assume there's enough space (as the code does at present)
|
||||
iUdp.write((uint8_t*)&iRequestId, sizeof(iRequestId));
|
||||
|
||||
twoByteBuffer = htons(QUERY_FLAG | OPCODE_STANDARD_QUERY | RECURSION_DESIRED_FLAG);
|
||||
iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
|
||||
|
||||
twoByteBuffer = htons(1); // One question record
|
||||
iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
|
||||
|
||||
twoByteBuffer = 0; // Zero answer records
|
||||
iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
|
||||
|
||||
iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
|
||||
// and zero additional records
|
||||
iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
|
||||
|
||||
// Build question
|
||||
const char* start =aName;
|
||||
const char* end =start;
|
||||
uint8_t len;
|
||||
// Run through the name being requested
|
||||
while (*end) {
|
||||
// Find out how long this section of the name is
|
||||
end = start;
|
||||
while (*end && (*end != '.') ) {
|
||||
end++;
|
||||
}
|
||||
|
||||
if (end-start > 0) {
|
||||
// Write out the size of this section
|
||||
len = end-start;
|
||||
iUdp.write(&len, sizeof(len));
|
||||
// And then write out the section
|
||||
iUdp.write((uint8_t*)start, end-start);
|
||||
}
|
||||
start = end+1;
|
||||
}
|
||||
|
||||
// We've got to the end of the question name, so terminate it with a zero-length section
|
||||
len = 0;
|
||||
iUdp.write(&len, sizeof(len));
|
||||
// Finally the type and class of question
|
||||
twoByteBuffer = htons(TYPE_A);
|
||||
iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
|
||||
|
||||
twoByteBuffer = htons(CLASS_IN); // Internet class of question
|
||||
iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
|
||||
// Success! Everything buffered okay
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int DNSClient::ProcessResponse(uint32_t aTimeout, IPAddress& aAddress) {
|
||||
uint32_t startTime = millis();
|
||||
|
||||
// Wait for a response packet
|
||||
while(iUdp.parsePacket() <= 0) {
|
||||
if ((millis() - startTime) > aTimeout) {
|
||||
return TIMED_OUT;
|
||||
}
|
||||
delay(20);
|
||||
}
|
||||
|
||||
// We've had a reply!
|
||||
// Read the UDP header
|
||||
uint8_t header[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header
|
||||
// Check that it's a response from the right server and the right port
|
||||
if ( (iDNSServer != iUdp.remoteIP()) || (iUdp.remotePort() != DNS_PORT) ) {
|
||||
// It's not from who we expected
|
||||
return INVALID_SERVER;
|
||||
}
|
||||
|
||||
// Read through the rest of the response
|
||||
if (iUdp.available() < DNS_HEADER_SIZE) {
|
||||
return TRUNCATED;
|
||||
}
|
||||
iUdp.read(header, DNS_HEADER_SIZE);
|
||||
|
||||
uint16_t staging; // Staging used to avoid type-punning warnings
|
||||
memcpy(&staging, &header[2], sizeof(uint16_t));
|
||||
uint16_t header_flags = htons(staging);
|
||||
memcpy(&staging, &header[0], sizeof(uint16_t));
|
||||
// Check that it's a response to this request
|
||||
if ( (iRequestId != staging) || ((header_flags & QUERY_RESPONSE_MASK) != (uint16_t)RESPONSE_FLAG) ) {
|
||||
// Mark the entire packet as read
|
||||
iUdp.flush();
|
||||
return INVALID_RESPONSE;
|
||||
}
|
||||
// Check for any errors in the response (or in our request)
|
||||
// although we don't do anything to get round these
|
||||
if ( (header_flags & TRUNCATION_FLAG) || (header_flags & RESP_MASK) ) {
|
||||
// Mark the entire packet as read
|
||||
iUdp.flush();
|
||||
return -5; // INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
// And make sure we've got (at least) one answer
|
||||
memcpy(&staging, &header[6], sizeof(uint16_t));
|
||||
uint16_t answerCount = htons(staging);
|
||||
if (answerCount == 0 ) {
|
||||
// Mark the entire packet as read
|
||||
iUdp.flush();
|
||||
return -6; // INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
// Skip over any questions
|
||||
memcpy(&staging, &header[4], sizeof(uint16_t));
|
||||
for (uint32_t i = 0; i < htons(staging); i++) {
|
||||
// Skip over the name
|
||||
uint8_t len;
|
||||
do {
|
||||
iUdp.read(&len, sizeof(len));
|
||||
if (len > 0) {
|
||||
// Don't need to actually read the data out for the string, just
|
||||
// advance ptr to beyond it
|
||||
while(len--) {
|
||||
iUdp.read(); // we don't care about the returned byte
|
||||
}
|
||||
}
|
||||
} while (len != 0);
|
||||
|
||||
// Now jump over the type and class
|
||||
for (uint32_t i = 0; i < 4; i++) {
|
||||
iUdp.read(); // we don't care about the returned byte
|
||||
}
|
||||
}
|
||||
|
||||
// Now we're up to the bit we're interested in, the answer
|
||||
// There might be more than one answer (although we'll just use the first
|
||||
// type A answer) and some authority and additional resource records but
|
||||
// we're going to ignore all of them.
|
||||
|
||||
for (uint32_t i = 0; i < answerCount; i++) {
|
||||
// Skip the name
|
||||
uint8_t len;
|
||||
do {
|
||||
iUdp.read(&len, sizeof(len));
|
||||
if ((len & LABEL_COMPRESSION_MASK) == 0) {
|
||||
// It's just a normal label
|
||||
if (len > 0) {
|
||||
// And it's got a length
|
||||
// Don't need to actually read the data out for the string,
|
||||
// just advance ptr to beyond it
|
||||
while(len--) {
|
||||
iUdp.read(); // we don't care about the returned byte
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This is a pointer to a somewhere else in the message for the
|
||||
// rest of the name. We don't care about the name, and RFC1035
|
||||
// says that a name is either a sequence of labels ended with a
|
||||
// 0 length octet or a pointer or a sequence of labels ending in
|
||||
// a pointer. Either way, when we get here we're at the end of
|
||||
// the name
|
||||
// Skip over the pointer
|
||||
iUdp.read(); // we don't care about the returned byte
|
||||
// And set len so that we drop out of the name loop
|
||||
len = 0;
|
||||
}
|
||||
} while (len != 0);
|
||||
|
||||
// Check the type and class
|
||||
uint16_t answerType;
|
||||
uint16_t answerClass;
|
||||
iUdp.read((uint8_t*)&answerType, sizeof(answerType));
|
||||
iUdp.read((uint8_t*)&answerClass, sizeof(answerClass));
|
||||
|
||||
// Ignore the Time-To-Live as we don't do any caching
|
||||
for (uint32_t i = 0; i < TTL_SIZE; i++) {
|
||||
iUdp.read(); // We don't care about the returned byte
|
||||
}
|
||||
|
||||
// And read out the length of this answer
|
||||
// Don't need header_flags anymore, so we can reuse it here
|
||||
iUdp.read((uint8_t*)&header_flags, sizeof(header_flags));
|
||||
|
||||
if ( (htons(answerType) == TYPE_A) && (htons(answerClass) == CLASS_IN) ) {
|
||||
if (htons(header_flags) != 4) {
|
||||
// It's a weird size
|
||||
// Mark the entire packet as read
|
||||
iUdp.flush();
|
||||
return -9; // INVALID_RESPONSE;
|
||||
}
|
||||
iUdp.read(aAddress.raw_address(), 4);
|
||||
// uint32_t address;
|
||||
// iUdp.read((uint8_t*)&address, sizeof(address));
|
||||
// aAddress = (IPAddress)address;
|
||||
|
||||
// Check we've got a valid address
|
||||
if ((0xFFFFFFFF != (uint32_t)aAddress) && (0 != (uint32_t)aAddress)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
} else {
|
||||
// This isn't an answer type we're after, move onto the next one
|
||||
for (uint32_t i = 0; i < htons(header_flags); i++) {
|
||||
iUdp.read(); // we don't care about the returned byte
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mark the entire packet as read
|
||||
iUdp.flush();
|
||||
|
||||
// If we get here then we haven't found an answer
|
||||
return -10; // INVALID_RESPONSE;
|
||||
}
|
42
lib/default/DnsClient/src/DnsClient.h
Normal file
42
lib/default/DnsClient/src/DnsClient.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
DnsClient.h - DNS client for Arduino
|
||||
|
||||
SPDX-FileCopyrightText: 2009-2010 MCQN Ltd. and Theo Arends
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
// Arduino DNS client for WizNet5100-based Ethernet shield
|
||||
// (c) Copyright 2009-2010 MCQN Ltd.
|
||||
// Released under Apache License, version 2.0
|
||||
|
||||
#ifndef DNSClient_h
|
||||
#define DNSClient_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <IPAddress.h>
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
class DNSClient {
|
||||
public:
|
||||
void begin(const IPAddress& aDNSServer);
|
||||
void setTimeout(uint32_t aTimeout = 1000);
|
||||
|
||||
/* Resolve the given hostname to an IP address.
|
||||
@param aHostname Name to be resolved
|
||||
@param aResult IPAddress structure to store the returned IP address
|
||||
@result 1 if aIPAddrString was successfully converted to an IP address, else error code
|
||||
*/
|
||||
int getHostByName(const char* aHostname, IPAddress& aResult);
|
||||
|
||||
protected:
|
||||
int BuildRequest(const char* aName);
|
||||
int ProcessResponse(uint32_t aTimeout, IPAddress& aAddress);
|
||||
|
||||
IPAddress iDNSServer;
|
||||
uint16_t iRequestId;
|
||||
uint16_t iTimeout = 1000;
|
||||
WiFiUDP iUdp;
|
||||
};
|
||||
|
||||
#endif
|
@ -71,3 +71,14 @@ void be_commonobj_delete(bvm *vm, bgcobject *obj)
|
||||
be_free(vm, co, sizeof(bcommomobj));
|
||||
}
|
||||
}
|
||||
|
||||
/* generic destroy method for comobj, just call be_os_free() on the pointer */
|
||||
int be_commonobj_destroy_generic(bvm* vm)
|
||||
{
|
||||
int argc = be_top(vm);
|
||||
if (argc > 0) {
|
||||
void * obj = be_tocomptr(vm, 1);
|
||||
if (obj != NULL) { be_os_free(obj); }
|
||||
}
|
||||
be_return_nil(vm);
|
||||
}
|
||||
|
@ -259,5 +259,6 @@ typedef const char* (*breader)(void*, size_t*);
|
||||
const char* be_vtype2str(bvalue *v);
|
||||
bvalue* be_indexof(bvm *vm, int idx);
|
||||
void be_commonobj_delete(bvm *vm, bgcobject *obj);
|
||||
int be_commonobj_destroy_generic(bvm* vm);
|
||||
|
||||
#endif
|
||||
|
@ -35,12 +35,14 @@ static void int64_toa(int64_t num, uint8_t* str) {
|
||||
void* int64_init(bvm *vm, int32_t val) {
|
||||
int64_t *i64 = (int64_t*)be_malloc(vm, sizeof(int64_t));
|
||||
*i64 = (int64_t) val;
|
||||
// serial_debug("int64_init p=%p\n", i64);
|
||||
return i64;
|
||||
}
|
||||
BE_FUNC_CTYPE_DECLARE(int64_init, "+_p", "@[i]")
|
||||
|
||||
void int64_deinit(bvm *vm, int64_t *i64) {
|
||||
// TODO
|
||||
// serial_debug("int64_deinit p=%p\n", i64);
|
||||
be_free(vm, i64, sizeof(int64_t));
|
||||
}
|
||||
BE_FUNC_CTYPE_DECLARE(int64_deinit, "", "@.")
|
||||
|
||||
@ -168,7 +170,6 @@ void* int64_tobytes(int64_t *i64, size_t *len) {
|
||||
BE_FUNC_CTYPE_DECLARE(int64_tobytes, "&", ".")
|
||||
|
||||
void int64_frombytes(int64_t *i64, uint8_t* ptr, size_t len, int32_t idx) {
|
||||
serial_debug("int64_frombytes p=%p len=%i idx=%i\n", ptr, len, idx);
|
||||
if (idx < 0) { idx = len + idx; } // support negative index, counting from the end
|
||||
if (idx < 0) { idx = 0; } // sanity check
|
||||
if (idx > len) { idx = len; }
|
||||
|
@ -10,18 +10,6 @@
|
||||
#include "be_exec.h"
|
||||
#include "esp_rom_md5.h"
|
||||
|
||||
int free_ctx(bvm* vm) {
|
||||
int argc = be_top(vm);
|
||||
if (argc > 0) {
|
||||
be_getmember(vm, 1, ".p");
|
||||
md5_context_t * ctx = (md5_context_t *) be_tocomptr(vm, -1);
|
||||
if (ctx != NULL) {
|
||||
be_os_free(ctx);
|
||||
}
|
||||
}
|
||||
be_return_nil(vm);
|
||||
}
|
||||
|
||||
// `Md5.init() -> `
|
||||
int32_t m_md5_init(struct bvm *vm);
|
||||
int32_t m_md5_init(struct bvm *vm) {
|
||||
@ -32,7 +20,7 @@ int32_t m_md5_init(struct bvm *vm) {
|
||||
}
|
||||
esp_rom_md5_init(ctx);
|
||||
|
||||
be_newcomobj(vm, ctx, &free_ctx);
|
||||
be_newcomobj(vm, ctx, &be_commonobj_destroy_generic);
|
||||
be_setmember(vm, 1, ".p");
|
||||
be_return_nil(vm);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
*******************************************************************/
|
||||
#include "be_constobj.h"
|
||||
#include "be_mem.h"
|
||||
#include "be_object.h"
|
||||
#include "re1.5.h"
|
||||
|
||||
/********************************************************************
|
||||
@ -33,15 +34,6 @@ re.split = def (regex_str, str) end # native
|
||||
|
||||
extern const bclass be_class_re_pattern;
|
||||
|
||||
int be_free_comobj(bvm* vm) {
|
||||
int argc = be_top(vm);
|
||||
if (argc > 0) {
|
||||
void * obj = be_tocomptr(vm, 1);
|
||||
if (obj != NULL) { be_os_free(obj); }
|
||||
}
|
||||
be_return_nil(vm);
|
||||
}
|
||||
|
||||
// Native functions be_const_func()
|
||||
// Berry: `re.compile(pattern:string) -> instance(be_pattern)`
|
||||
int be_re_compile(bvm *vm) {
|
||||
@ -60,7 +52,7 @@ int be_re_compile(bvm *vm) {
|
||||
}
|
||||
be_pushntvclass(vm, &be_class_re_pattern);
|
||||
be_call(vm, 0);
|
||||
be_newcomobj(vm, code, &be_free_comobj);
|
||||
be_newcomobj(vm, code, &be_commonobj_destroy_generic);
|
||||
be_setmember(vm, -2, "_p");
|
||||
be_pop(vm, 1);
|
||||
be_return(vm);
|
||||
|
Binary file not shown.
@ -1,2 +1,2 @@
|
||||
# rm Partition_wizard.tapp; zip -j -0 Partition_wizard.tapp Partition_Wizard/*
|
||||
# rm Partition_Wizard.tapp; zip -j -0 Partition_Wizard.tapp Partition_Wizard/*
|
||||
import partition_wizard
|
||||
|
Binary file not shown.
@ -480,7 +480,7 @@ class Partition_wizard_UI
|
||||
webserver.content_send("<fieldset><legend><b> Migrate to safeboot partition layout </b></legend><p></p>")
|
||||
|
||||
webserver.content_send("<p>The `safeboot` layout allows for increased size<br>of firmware or file-system.</p>")
|
||||
webserver.content_send("<p>Please see <a href=''>Safeboot layout documentation</a></p>")
|
||||
webserver.content_send("<p>Please see <a href='https://tasmota.github.io/docs/Safeboot/' target='_blank'>Safeboot layout documentation</a></p>")
|
||||
webserver.content_send("<p> </p>")
|
||||
|
||||
webserver.content_send(string.format("<p>Step 1: %s</p>", self.display_step_state(self.test_step_1(p), "boot on `app1`")))
|
||||
@ -558,7 +558,7 @@ class Partition_wizard_UI
|
||||
|
||||
# display if layout is factory
|
||||
if self.has_factory_layout(p)
|
||||
webserver.content_send("<p>This device uses the <b>safeboot</b> layout</p>")
|
||||
webserver.content_send("<p>This device uses the <a href='https://tasmota.github.io/docs/Safeboot/' target='_blank'>Safeboot</a> layout</p>")
|
||||
end
|
||||
|
||||
webserver.content_send("</fieldset><p></p>")
|
||||
|
@ -317,6 +317,7 @@
|
||||
#define D_WCFG_5_WAIT "Wait"
|
||||
#define D_WCFG_6_SERIAL "Serial"
|
||||
#define D_WCFG_7_WIFIMANAGER_RESET_ONLY "ManagerRst"
|
||||
#define D_CMND_DNSTIMEOUT "DnsTimeout"
|
||||
#define D_CMND_DEVICENAME "DeviceName"
|
||||
#define D_CMND_FRIENDLYNAME "FriendlyName"
|
||||
#define D_CMND_FN "FN"
|
||||
|
@ -268,6 +268,10 @@ String EthernetMacAddress(void);
|
||||
#define TASM_FILE_AUTOEXEC "/autoexec.bat" // Commands executed after restart
|
||||
#define TASM_FILE_CONFIG "/config.sys" // Settings executed after restart
|
||||
|
||||
#ifndef DNS_TIMEOUT
|
||||
#define DNS_TIMEOUT 1000 // Milliseconds
|
||||
#endif
|
||||
|
||||
#ifndef MQTT_MAX_PACKET_SIZE
|
||||
#define MQTT_MAX_PACKET_SIZE 1200 // Bytes
|
||||
//#define MQTT_MAX_PACKET_SIZE 2048 // Bytes
|
||||
|
@ -675,8 +675,9 @@ typedef struct {
|
||||
uint8_t knx_CB_registered; // 4A8 Number of Group Address to write
|
||||
uint8_t switchmode[MAX_SWITCHES_SET]; // 4A9
|
||||
|
||||
uint8_t free_4c5[5]; // 4C5
|
||||
uint8_t free_4c5[3]; // 4C5
|
||||
|
||||
uint16_t dns_timeout; // 4C8
|
||||
uint8_t ds3502_state[MAX_DS3502]; // 4CA
|
||||
uint16_t influxdb_port; // 4CE
|
||||
power_t interlock[MAX_INTERLOCKS_SET]; // 4D0 MAX_INTERLOCKS = MAX_RELAYS / 2
|
||||
|
@ -20,6 +20,6 @@
|
||||
#ifndef _TASMOTA_VERSION_H_
|
||||
#define _TASMOTA_VERSION_H_
|
||||
|
||||
const uint32_t VERSION = 0x0C000100; // 12.0.1.0
|
||||
const uint32_t VERSION = 0x0C000200; // 12.0.2.0
|
||||
|
||||
#endif // _TASMOTA_VERSION_H_
|
||||
|
@ -79,6 +79,7 @@
|
||||
#define WIFI_CONFIG_TOOL WIFI_RETRY // [WifiConfig] Default tool if Wi-Fi fails to connect (default option: 4 - WIFI_RETRY)
|
||||
// (WIFI_RESTART, WIFI_MANAGER, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, WIFI_MANAGER_RESET_ONLY)
|
||||
// The configuration can be changed after first setup using WifiConfig 0, 2, 4, 5, 6 and 7.
|
||||
#define DNS_TIMEOUT 1000 // [DnsTimeout] Number of ms before DNS timeout
|
||||
#define WIFI_ARP_INTERVAL 60 // [SetOption41] Send gratuitous ARP interval
|
||||
#define WIFI_SCAN_AT_RESTART false // [SetOption56] Scan Wi-Fi network at restart for configured AP's
|
||||
#define WIFI_SCAN_REGULARLY true // [SetOption57] Scan Wi-Fi network every 44 minutes for configured AP's
|
||||
|
@ -35,6 +35,7 @@
|
||||
// Libraries
|
||||
#include <ESP8266HTTPClient.h> // Ota
|
||||
#include <ESP8266httpUpdate.h> // Ota
|
||||
#include <DnsClient.h> // Any getHostByName
|
||||
#ifdef ESP32
|
||||
#ifdef USE_TLS
|
||||
#include "HTTPUpdateLight.h" // Ota over HTTPS for ESP32
|
||||
@ -125,8 +126,7 @@ typedef struct {
|
||||
int32_t energy_kWhtoday_ph[3]; // 2D8
|
||||
int32_t energy_kWhtotal_ph[3]; // 2E4
|
||||
int32_t energy_kWhexport_ph[3]; // 2F0
|
||||
|
||||
uint8_t free_2fc[4]; // 2FC
|
||||
uint32_t utc_time; // 2FC
|
||||
} TRtcSettings;
|
||||
TRtcSettings RtcSettings;
|
||||
#ifdef ESP32
|
||||
@ -159,6 +159,7 @@ struct XDRVMAILBOX {
|
||||
char *command;
|
||||
} XdrvMailbox;
|
||||
|
||||
DNSClient DnsClient;
|
||||
WiFiUDP PortUdp; // UDP Syslog and Alexa
|
||||
|
||||
#ifdef ESP32
|
||||
@ -589,6 +590,7 @@ void setup(void) {
|
||||
TasmotaGlobal.init_state = INIT_GPIOS;
|
||||
|
||||
SetPowerOnState();
|
||||
DnsClient.setTimeout(Settings->dns_timeout);
|
||||
WifiConnect();
|
||||
|
||||
AddLog(LOG_LEVEL_INFO, PSTR(D_PROJECT " %s - %s " D_VERSION " %s%s-" ARDUINO_CORE_RELEASE "(%s)"),
|
||||
|
@ -37,6 +37,9 @@ uint32_t GetRtcSettingsCrc(void) {
|
||||
|
||||
void RtcSettingsSave(void) {
|
||||
RtcSettings.baudrate = Settings->baudrate * 300;
|
||||
if (UtcTime() > START_VALID_TIME) { // 2016-01-01
|
||||
RtcSettings.utc_time = UtcTime();
|
||||
}
|
||||
if (GetRtcSettingsCrc() != rtc_settings_crc) {
|
||||
|
||||
if (RTC_MEM_VALID != RtcSettings.valid) {
|
||||
@ -923,6 +926,7 @@ void SettingsDefaultSet2(void) {
|
||||
flag3.use_wifi_scan |= WIFI_SCAN_AT_RESTART;
|
||||
flag3.use_wifi_rescan |= WIFI_SCAN_REGULARLY;
|
||||
Settings->wifi_output_power = 170;
|
||||
Settings->dns_timeout = DNS_TIMEOUT;
|
||||
Settings->param[P_ARP_GRATUITOUS] = WIFI_ARP_INTERVAL;
|
||||
ParseIPv4(&Settings->ipv4_address[0], PSTR(WIFI_IP_ADDRESS));
|
||||
ParseIPv4(&Settings->ipv4_address[1], PSTR(WIFI_GATEWAY));
|
||||
@ -1537,6 +1541,9 @@ void SettingsDelta(void) {
|
||||
Settings->weight_offset = Settings->energy_frequency_calibration * Settings->weight_calibration;
|
||||
#endif
|
||||
}
|
||||
if (Settings->version < 0x0C000102) { // 12.0.1.2
|
||||
Settings->dns_timeout = DNS_TIMEOUT;
|
||||
}
|
||||
|
||||
Settings->version = VERSION;
|
||||
SettingsSave(1);
|
||||
|
@ -2452,11 +2452,10 @@ void SyslogAsync(bool refresh) {
|
||||
uint32_t current_hash = GetHash(SettingsText(SET_SYSLOG_HOST), strlen(SettingsText(SET_SYSLOG_HOST)));
|
||||
if (syslog_host_hash != current_hash) {
|
||||
IPAddress temp_syslog_host_addr;
|
||||
int ok = WiFi.hostByName(SettingsText(SET_SYSLOG_HOST), temp_syslog_host_addr); // If sleep enabled this might result in exception so try to do it once using hash
|
||||
if (!ok || (0xFFFFFFFF == (uint32_t)temp_syslog_host_addr)) { // 255.255.255.255 is assumed a DNS problem
|
||||
if (!WifiHostByName(SettingsText(SET_SYSLOG_HOST), temp_syslog_host_addr)) { // If sleep enabled this might result in exception so try to do it once using hash
|
||||
TasmotaGlobal.syslog_level = 0;
|
||||
TasmotaGlobal.syslog_timer = SYSLOG_TIMER;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "Loghost DNS resolve failed (%s). " D_RETRY_IN " %d " D_UNIT_SECOND), SettingsText(SET_SYSLOG_HOST), SYSLOG_TIMER);
|
||||
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RETRY_IN " %d " D_UNIT_SECOND), SYSLOG_TIMER);
|
||||
return;
|
||||
}
|
||||
syslog_host_hash = current_hash;
|
||||
|
@ -30,7 +30,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix
|
||||
D_CMND_MODULE "|" D_CMND_MODULES "|" D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_TEMPLATE "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|"
|
||||
D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SYSLOG "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|"
|
||||
D_CMND_SERIALBUFFER "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALCONFIG "|" D_CMND_SERIALDELIMITER "|"
|
||||
D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_WIFI "|"
|
||||
D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_WIFI "|" D_CMND_DNSTIMEOUT "|"
|
||||
D_CMND_DEVICENAME "|" D_CMND_FN "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|"
|
||||
D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_LEDPWM_ON "|" D_CMND_LEDPWM_OFF "|" D_CMND_LEDPWM_MODE "|"
|
||||
D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM"|" D_CMND_SWITCHTEXT "|"
|
||||
@ -65,7 +65,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = {
|
||||
&CmndModule, &CmndModules, &CmndGpio, &CmndGpios, &CmndTemplate, &CmndPwm, &CmndPwmfrequency, &CmndPwmrange,
|
||||
&CmndButtonDebounce, &CmndSwitchDebounce, &CmndSyslog, &CmndLoghost, &CmndLogport,
|
||||
&CmndSerialBuffer, &CmndSerialSend, &CmndBaudrate, &CmndSerialConfig, &CmndSerialDelimiter,
|
||||
&CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndWifi,
|
||||
&CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndWifi, &CmndDnsTimeout,
|
||||
&CmndDevicename, &CmndFriendlyname, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd,
|
||||
&CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode,
|
||||
&CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndSwitchText,
|
||||
@ -2277,6 +2277,15 @@ void CmndWifi(void)
|
||||
Response_P(PSTR("{\"" D_JSON_WIFI "\":\"%s\",\"" D_JSON_WIFI_MODE "\":\"11%c\"}"), GetStateText(Settings->flag4.network_wifi), pgm_read_byte(&kWifiPhyMode[WiFi.getPhyMode() & 0x3]) );
|
||||
}
|
||||
|
||||
void CmndDnsTimeout(void) {
|
||||
// Set timeout between 100 and 20000 mSec
|
||||
if ((XdrvMailbox.payload >= 100) && (XdrvMailbox.payload <= 20000)) {
|
||||
Settings->dns_timeout = XdrvMailbox.payload;
|
||||
DnsClient.setTimeout(Settings->dns_timeout);
|
||||
}
|
||||
ResponseCmndNumber(Settings->dns_timeout);
|
||||
}
|
||||
|
||||
#ifdef USE_I2C
|
||||
void CmndI2cScan(void)
|
||||
{
|
||||
|
@ -489,10 +489,15 @@ void RtcInit(void) {
|
||||
|
||||
if (Settings->cfg_timestamp > START_VALID_TIME) {
|
||||
// Fix file timestamp while utctime is not synced
|
||||
uint32_t local_time = Settings->cfg_timestamp +1;
|
||||
RtcGetDaylightSavingTimes(local_time);
|
||||
local_time += RtcTimeZoneOffset(local_time);
|
||||
uint32_t utc_time = Settings->cfg_timestamp;
|
||||
if (RtcSettings.utc_time > utc_time) {
|
||||
utc_time = RtcSettings.utc_time;
|
||||
}
|
||||
utc_time++;
|
||||
RtcGetDaylightSavingTimes(utc_time);
|
||||
uint32_t local_time = utc_time + RtcTimeZoneOffset(utc_time);
|
||||
RtcSetTimeOfDay(local_time);
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("RTC: Timestamp %s"), GetDT(local_time).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -729,20 +729,20 @@ void wifiKeepAlive(void) {
|
||||
}
|
||||
#endif // ESP8266
|
||||
|
||||
int WifiHostByName(const char* aHostname, IPAddress& aResult) {
|
||||
bool WifiHostByName(const char* aHostname, IPAddress& aResult) {
|
||||
// Use this instead of WiFi.hostByName or connect(host_name,.. to block less if DNS server is not found
|
||||
aResult = (uint32_t)(0);
|
||||
if (aResult.fromString(aHostname)) {
|
||||
// Host name is already an IP address so use it!
|
||||
return 1;
|
||||
uint32_t dns_address = (!TasmotaGlobal.global_state.eth_down) ? Settings->eth_ipv4_address[3] : Settings->ipv4_address[3];
|
||||
DnsClient.begin((IPAddress)dns_address);
|
||||
if (DnsClient.getHostByName(aHostname, aResult) != 1) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("DNS: Unable to resolve '%s'"), aHostname);
|
||||
return false;
|
||||
}
|
||||
else if (WiFi.hostByName(aHostname, aResult)) {
|
||||
// Host name resolved
|
||||
if (0xFFFFFFFF != (uint32_t)aResult) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiDnsPresent(const char* aHostname) {
|
||||
IPAddress aResult;
|
||||
return WifiHostByName(aHostname, aResult);
|
||||
}
|
||||
|
||||
void WifiPollNtp() {
|
||||
@ -802,7 +802,7 @@ uint32_t WifiGetNtp(void) {
|
||||
}
|
||||
if (!WifiHostByName(ntp_server, time_server_ip)) {
|
||||
ntp_server_id++;
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Unable to resolve '%s'"), ntp_server);
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Unable to resolve '%s'"), ntp_server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -992,8 +992,6 @@ void MqttConnected(void) {
|
||||
}
|
||||
|
||||
void MqttReconnect(void) {
|
||||
char stopic[TOPSZ];
|
||||
|
||||
Mqtt.allowed = Settings->flag.mqtt_enabled && (TasmotaGlobal.restart_flag == 0); // SetOption3 - Enable MQTT, and don't connect if restart in process
|
||||
if (Mqtt.allowed) {
|
||||
#if defined(USE_MQTT_AZURE_DPS_SCOPEID) && defined(USE_MQTT_AZURE_DPS_PRESHAREDKEY)
|
||||
@ -1040,6 +1038,23 @@ void MqttReconnect(void) {
|
||||
|
||||
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT D_ATTEMPTING_CONNECTION));
|
||||
|
||||
if (MqttClient.connected()) { MqttClient.disconnect(); }
|
||||
|
||||
MqttSetClientTimeout();
|
||||
|
||||
MqttClient.setCallback(MqttDataHandler);
|
||||
|
||||
// Keep using hostname to solve rc -4 issues
|
||||
if (!WifiDnsPresent(SettingsText(SET_MQTT_HOST))) {
|
||||
MqttDisconnected(-5); // MQTT_DNS_DISCONNECTED
|
||||
return;
|
||||
}
|
||||
MqttClient.setServer(SettingsText(SET_MQTT_HOST), Settings->mqtt_port);
|
||||
|
||||
if (2 == Mqtt.initial_connection_state) { // Executed once just after power on and wifi is connected
|
||||
Mqtt.initial_connection_state = 1;
|
||||
}
|
||||
|
||||
char *mqtt_user = nullptr;
|
||||
char *mqtt_pwd = nullptr;
|
||||
if (strlen(SettingsText(SET_MQTT_USER))) {
|
||||
@ -1049,49 +1064,37 @@ void MqttReconnect(void) {
|
||||
mqtt_pwd = SettingsText(SET_MQTT_PWD);
|
||||
}
|
||||
|
||||
GetTopic_P(stopic, TELE, TasmotaGlobal.mqtt_topic, S_LWT);
|
||||
Response_P(S_LWT_OFFLINE);
|
||||
|
||||
if (MqttClient.connected()) { MqttClient.disconnect(); }
|
||||
|
||||
MqttSetClientTimeout();
|
||||
|
||||
#ifdef USE_MQTT_TLS
|
||||
uint32_t mqtt_connect_time = millis();
|
||||
if (Mqtt.mqtt_tls) {
|
||||
tlsClient->stop();
|
||||
} else {
|
||||
// EspClient = WiFiClient(); // Wifi Client reconnect issue 4497 (https://github.com/esp8266/Arduino/issues/4497)
|
||||
MqttClient.setClient(EspClient);
|
||||
}
|
||||
#else
|
||||
// EspClient = WiFiClient(); // Wifi Client reconnect issue 4497 (https://github.com/esp8266/Arduino/issues/4497)
|
||||
MqttClient.setClient(EspClient);
|
||||
#endif
|
||||
|
||||
if (2 == Mqtt.initial_connection_state) { // Executed once just after power on and wifi is connected
|
||||
Mqtt.initial_connection_state = 1;
|
||||
}
|
||||
|
||||
MqttClient.setCallback(MqttDataHandler);
|
||||
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
|
||||
#ifdef USE_MQTT_AWS_IOT
|
||||
// re-assign private keys in case it was updated in between
|
||||
if (Mqtt.mqtt_tls) {
|
||||
if ((nullptr != AWS_IoT_Private_Key) && (nullptr != AWS_IoT_Client_Certificate)) {
|
||||
// if private key is there, we remove user/pwd
|
||||
mqtt_user = nullptr;
|
||||
mqtt_pwd = nullptr;
|
||||
tlsClient->setClientECCert(AWS_IoT_Client_Certificate,
|
||||
AWS_IoT_Private_Key,
|
||||
0xFFFF /* all usages, don't care */, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
IPAddress mqtt_host_ip;
|
||||
if (!WifiHostByName(SettingsText(SET_MQTT_HOST), mqtt_host_ip)) {
|
||||
MqttDisconnected(-5); // MQTT_DNS_DISCONNECTED
|
||||
return;
|
||||
#endif // USE_MQTT_AWS_IOT
|
||||
#ifdef USE_MQTT_AZURE_IOT
|
||||
String azureMqtt_password = SettingsText(SET_MQTT_PWD);
|
||||
if (azureMqtt_password.indexOf("SharedAccessSignature") == -1) {
|
||||
// assuming a PreSharedKey was provided, calculating a SAS Token into azureMqtt_password
|
||||
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "Authenticating with an Azure IoT Hub Token"));
|
||||
azureMqtt_password = AzurePSKtoToken(SettingsText(SET_MQTT_HOST), SettingsText(SET_MQTT_CLIENT), SettingsText(SET_MQTT_PWD));
|
||||
}
|
||||
MqttClient.setServer(mqtt_host_ip, Settings->mqtt_port);
|
||||
|
||||
uint32_t mqtt_connect_time = millis();
|
||||
#if defined(USE_MQTT_TLS)
|
||||
String azureMqtt_userString = String(SettingsText(SET_MQTT_HOST)) + "/" + String(SettingsText(SET_MQTT_CLIENT)); + "/?api-version=2018-06-30";
|
||||
mqtt_user = (char*)azureMqtt_userString.c_str();
|
||||
mqtt_pwd = (char*)azureMqtt_password.c_str();
|
||||
#endif // USE_MQTT_AZURE_IOT
|
||||
bool allow_all_fingerprints = false;
|
||||
bool learn_fingerprint1 = false;
|
||||
bool learn_fingerprint2 = false;
|
||||
@ -1105,31 +1108,21 @@ void MqttReconnect(void) {
|
||||
allow_all_fingerprints |= learn_fingerprint2;
|
||||
tlsClient->setPubKeyFingerprint(Settings->mqtt_fingerprint[0], Settings->mqtt_fingerprint[1], allow_all_fingerprints);
|
||||
}
|
||||
#endif
|
||||
bool lwt_retain = Settings->flag4.mqtt_no_retain ? false : true; // no retained last will if "no_retain"
|
||||
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
|
||||
if (Mqtt.mqtt_tls) {
|
||||
if ((nullptr != AWS_IoT_Private_Key) && (nullptr != AWS_IoT_Client_Certificate)) {
|
||||
// if private key is there, we remove user/pwd
|
||||
mqtt_user = nullptr;
|
||||
mqtt_pwd = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else // No USE_MQTT_TLS
|
||||
MqttClient.setClient(EspClient);
|
||||
#endif // USE_MQTT_TLS
|
||||
|
||||
#ifdef USE_MQTT_AZURE_IOT
|
||||
String azureMqtt_password = SettingsText(SET_MQTT_PWD);
|
||||
if (azureMqtt_password.indexOf("SharedAccessSignature") == -1) {
|
||||
// assuming a PreSharedKey was provided, calculating a SAS Token into azureMqtt_password
|
||||
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "Authenticating with an Azure IoT Hub Token"));
|
||||
azureMqtt_password = AzurePSKtoToken(SettingsText(SET_MQTT_HOST), SettingsText(SET_MQTT_CLIENT), SettingsText(SET_MQTT_PWD));
|
||||
}
|
||||
|
||||
String azureMqtt_userString = String(SettingsText(SET_MQTT_HOST)) + "/" + String(SettingsText(SET_MQTT_CLIENT)); + "/?api-version=2018-06-30";
|
||||
if (MqttClient.connect(TasmotaGlobal.mqtt_client, azureMqtt_userString.c_str(), azureMqtt_password.c_str(), stopic, 1, lwt_retain, ResponseData(), Settings->flag5.mqtt_persistent ? 0:1)) {
|
||||
#else
|
||||
if (MqttClient.connect(TasmotaGlobal.mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, lwt_retain, ResponseData(), Settings->flag5.mqtt_persistent ? 0:1)) {
|
||||
#endif // USE_MQTT_AZURE_IOT
|
||||
char stopic[TOPSZ];
|
||||
GetTopic_P(stopic, TELE, TasmotaGlobal.mqtt_topic, S_LWT);
|
||||
Response_P(S_LWT_OFFLINE);
|
||||
if (MqttClient.connect(TasmotaGlobal.mqtt_client,
|
||||
mqtt_user,
|
||||
mqtt_pwd,
|
||||
stopic, // Will topic
|
||||
1, // Will QoS
|
||||
Settings->flag4.mqtt_no_retain ? false : true, // No retained last will if "no_retain",
|
||||
ResponseData(), // Will message
|
||||
Settings->flag5.mqtt_persistent ? 0 : 1)) { // Clean Session
|
||||
#ifdef USE_MQTT_TLS
|
||||
if (Mqtt.mqtt_tls) {
|
||||
#ifdef ESP8266
|
||||
|
@ -244,7 +244,7 @@ extern "C" {
|
||||
// -2: unable to resolve address
|
||||
int32_t t_ping_start(const char *hostname, uint32_t count) {
|
||||
IPAddress ipfull;
|
||||
if (!WiFi.hostByName(hostname, ipfull)) {
|
||||
if (!WifiHostByName(hostname, ipfull)) {
|
||||
ipfull = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
|
@ -105,8 +105,11 @@ String TelegramConnectToTelegram(const String &command) {
|
||||
|
||||
if (!TelegramInit()) { return ""; }
|
||||
|
||||
String host = F("api.telegram.org");
|
||||
String response = "";
|
||||
String host = F("api.telegram.org");
|
||||
if (!WifiDnsPresent(host.c_str())) {
|
||||
return response;
|
||||
}
|
||||
uint32_t tls_connect_time = millis();
|
||||
if (telegramClient->connect(host.c_str(), 443)) {
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include <berry.h>
|
||||
#include "be_mem.h"
|
||||
#include "be_object.h"
|
||||
|
||||
/*********************************************************************************************\
|
||||
* AES class
|
||||
@ -30,15 +31,6 @@
|
||||
\*********************************************************************************************/
|
||||
extern "C" {
|
||||
|
||||
int free_br_obj(bvm* vm) {
|
||||
int argc = be_top(vm);
|
||||
if (argc > 0) {
|
||||
void * obj = be_tocomptr(vm, 1);
|
||||
if (obj != NULL) { be_os_free(obj); }
|
||||
}
|
||||
be_return_nil(vm);
|
||||
}
|
||||
|
||||
// `AES_GCM.init(secret_key:bytes(32), iv:bytes(12)) -> instance`
|
||||
int32_t m_aes_gcm_init(struct bvm *vm);
|
||||
int32_t m_aes_gcm_init(struct bvm *vm) {
|
||||
@ -64,14 +56,14 @@ extern "C" {
|
||||
br_aes_small_ctr_keys * ctr_ctx = (br_aes_small_ctr_keys *) be_os_malloc(sizeof(br_aes_small_ctr_keys));
|
||||
if (!ctr_ctx) { be_throw(vm, BE_MALLOC_FAIL); }
|
||||
br_aes_small_ctr_init(ctr_ctx, bytes, length);
|
||||
be_newcomobj(vm, ctr_ctx, &free_br_obj);
|
||||
be_newcomobj(vm, ctr_ctx, &be_commonobj_destroy_generic);
|
||||
be_setmember(vm, 1, ".p1");
|
||||
|
||||
// Initialize an AES GCM structure based on this CTR engine
|
||||
br_gcm_context * gcm_ctx = (br_gcm_context *) be_os_malloc(sizeof(br_gcm_context));
|
||||
if (!gcm_ctx) { be_throw(vm, BE_MALLOC_FAIL); }
|
||||
br_gcm_init(gcm_ctx, &ctr_ctx->vtable, &br_ghash_ctmul32);
|
||||
be_newcomobj(vm, gcm_ctx, &free_br_obj);
|
||||
be_newcomobj(vm, gcm_ctx, &be_commonobj_destroy_generic);
|
||||
be_setmember(vm, 1, ".p2");
|
||||
|
||||
// Reset GCM context with provided IV
|
||||
|
Loading…
x
Reference in New Issue
Block a user