1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

Merge branch 'master' into feature/issue-2246-multi-wifi-hidden

This commit is contained in:
Erriez 2020-10-15 19:57:47 +02:00 committed by GitHub
commit 00673e05fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 1075 additions and 887 deletions

View File

@ -37,6 +37,7 @@ extern "C" {
#include "binary.h" #include "binary.h"
#include "esp8266_peri.h" #include "esp8266_peri.h"
#include "twi.h" #include "twi.h"
#include "core_esp8266_features.h" #include "core_esp8266_features.h"
#include "core_esp8266_version.h" #include "core_esp8266_version.h"
@ -125,15 +126,11 @@ void timer0_isr_init(void);
void timer0_attachInterrupt(timercallback userFunc); void timer0_attachInterrupt(timercallback userFunc);
void timer0_detachInterrupt(void); void timer0_detachInterrupt(void);
// Use stdlib abs() and round() to avoid issues with the C++ libraries
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#define radians(deg) ((deg)*DEG_TO_RAD) #define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG) #define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x)) #define sq(x) ((x)*(x))
void ets_intr_lock();
void ets_intr_unlock();
#define interrupts() xt_rsil(0) #define interrupts() xt_rsil(0)
#define noInterrupts() xt_rsil(15) #define noInterrupts() xt_rsil(15)
@ -162,11 +159,12 @@ typedef uint16_t word;
typedef bool boolean; typedef bool boolean;
typedef uint8_t byte; typedef uint8_t byte;
void ets_intr_lock();
void ets_intr_unlock();
void init(void); void init(void);
void initVariant(void); void initVariant(void);
int atexit(void (*func)()) __attribute__((weak));
void pinMode(uint8_t pin, uint8_t mode); void pinMode(uint8_t pin, uint8_t mode);
void digitalWrite(uint8_t pin, uint8_t val); void digitalWrite(uint8_t pin, uint8_t val);
int digitalRead(uint8_t pin); int digitalRead(uint8_t pin);
@ -212,21 +210,20 @@ void optimistic_yield(uint32_t interval_us);
} // extern "C" } // extern "C"
#endif #endif
// undefine stdlib's definitions when encountered, provide abs that supports floating point for C code
#ifndef __cplusplus
#undef abs
#define abs(x) ({ __typeof__(x) _x = (x); _x > 0 ? _x : -_x; })
#undef round
#define round(x) ({ __typeof__(x) _x = (x); _x >= 0 ? (long)(_x + 0.5) : (long)(_x - 0.5); })
#endif // ifndef __cplusplus
// from this point onward, we need to configure the c++ environment
#ifdef __cplusplus #ifdef __cplusplus
#include <algorithm> #include <algorithm>
#include <cstdlib>
#include <cmath> #include <cmath>
#include <pgmspace.h>
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
#include "Esp.h"
#include "Updater.h"
#include "debug.h"
using std::min; using std::min;
using std::max; using std::max;
@ -234,6 +231,10 @@ using std::round;
using std::isinf; using std::isinf;
using std::isnan; using std::isnan;
// Use float-compatible stl abs() and round(), we don't use Arduino macros to avoid issues with the C++ libraries
using std::abs;
using std::round;
#define _min(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a < _b? _a : _b; }) #define _min(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a < _b? _a : _b; })
#define _max(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a > _b? _a : _b; }) #define _max(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a > _b? _a : _b; })
@ -273,8 +274,19 @@ inline void configTzTime(const char* tz, const char* server1,
configTime(tz, server1, server2, server3); configTime(tz, server1, server2, server3);
} }
// Everything we expect to be implicitly loaded for the sketch
#include <pgmspace.h>
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
#include "Esp.h"
#include "Updater.h"
#endif // __cplusplus #endif // __cplusplus
#include "debug.h"
#include "pins_arduino.h" #include "pins_arduino.h"
#endif #endif

View File

@ -26,7 +26,9 @@
#include "MD5Builder.h" #include "MD5Builder.h"
#include "umm_malloc/umm_malloc.h" #include "umm_malloc/umm_malloc.h"
#include "cont.h" #include "cont.h"
#include "coredecls.h" #include "coredecls.h"
#include <pgmspace.h>
extern "C" { extern "C" {
#include "user_interface.h" #include "user_interface.h"
@ -40,11 +42,6 @@ extern struct rst_info resetInfo;
#ifndef PUYA_SUPPORT #ifndef PUYA_SUPPORT
#define PUYA_SUPPORT 1 #define PUYA_SUPPORT 1
#endif #endif
#ifndef PUYA_BUFFER_SIZE
// Good alternative for buffer size is: SPI_FLASH_SEC_SIZE (= 4k)
// Always use a multiple of flash page size (256 bytes)
#define PUYA_BUFFER_SIZE 256
#endif
/** /**
* User-defined Literals * User-defined Literals
@ -666,11 +663,14 @@ static SpiFlashOpResult spi_flash_write_puya(uint32_t offset, uint32_t *data, si
if (data == nullptr) { if (data == nullptr) {
return SPI_FLASH_RESULT_ERR; return SPI_FLASH_RESULT_ERR;
} }
if (size % 4 != 0) {
return SPI_FLASH_RESULT_ERR;
}
// PUYA flash chips need to read existing data, update in memory and write modified data again. // PUYA flash chips need to read existing data, update in memory and write modified data again.
static uint32_t *flash_write_puya_buf = nullptr; static uint32_t *flash_write_puya_buf = nullptr;
if (flash_write_puya_buf == nullptr) { if (flash_write_puya_buf == nullptr) {
flash_write_puya_buf = (uint32_t*) malloc(PUYA_BUFFER_SIZE); flash_write_puya_buf = (uint32_t*) malloc(FLASH_PAGE_SIZE);
// No need to ever free this, since the flash chip will never change at runtime. // No need to ever free this, since the flash chip will never change at runtime.
if (flash_write_puya_buf == nullptr) { if (flash_write_puya_buf == nullptr) {
// Memory could not be allocated. // Memory could not be allocated.
@ -684,45 +684,261 @@ static SpiFlashOpResult spi_flash_write_puya(uint32_t offset, uint32_t *data, si
uint32_t pos = offset; uint32_t pos = offset;
while (bytesLeft > 0 && rc == SPI_FLASH_RESULT_OK) { while (bytesLeft > 0 && rc == SPI_FLASH_RESULT_OK) {
size_t bytesNow = bytesLeft; size_t bytesNow = bytesLeft;
if (bytesNow > PUYA_BUFFER_SIZE) { if (bytesNow > FLASH_PAGE_SIZE) {
bytesNow = PUYA_BUFFER_SIZE; bytesNow = FLASH_PAGE_SIZE;
bytesLeft -= PUYA_BUFFER_SIZE; bytesLeft -= FLASH_PAGE_SIZE;
} else { } else {
bytesLeft = 0; bytesLeft = 0;
} }
size_t bytesAligned = (bytesNow + 3) & ~3; rc = spi_flash_read(pos, flash_write_puya_buf, bytesNow);
rc = spi_flash_read(pos, flash_write_puya_buf, bytesAligned);
if (rc != SPI_FLASH_RESULT_OK) { if (rc != SPI_FLASH_RESULT_OK) {
return rc; return rc;
} }
for (size_t i = 0; i < bytesAligned / 4; ++i) { for (size_t i = 0; i < bytesNow / 4; ++i) {
flash_write_puya_buf[i] &= *ptr; flash_write_puya_buf[i] &= *ptr;
++ptr; ++ptr;
} }
rc = spi_flash_write(pos, flash_write_puya_buf, bytesAligned); rc = spi_flash_write(pos, flash_write_puya_buf, bytesNow);
pos += bytesNow; pos += bytesNow;
} }
return rc; return rc;
} }
#endif #endif
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) { bool EspClass::flashReplaceBlock(uint32_t address, const uint8_t *value, uint32_t byteCount) {
SpiFlashOpResult rc = SPI_FLASH_RESULT_OK; uint32_t alignedAddress = (address & ~3);
uint32_t alignmentOffset = address - alignedAddress;
if (alignedAddress != ((address + byteCount - 1) & ~3)) {
// Only one 4 byte block is supported
return false;
}
#if PUYA_SUPPORT #if PUYA_SUPPORT
if (getFlashChipVendorId() == SPI_FLASH_VENDOR_PUYA) { if (getFlashChipVendorId() == SPI_FLASH_VENDOR_PUYA) {
rc = spi_flash_write_puya(offset, data, size); uint8_t tempData[4] __attribute__((aligned(4)));
if (spi_flash_read(alignedAddress, (uint32_t *)tempData, 4) != SPI_FLASH_RESULT_OK) {
return false;
}
for (size_t i = 0; i < byteCount; i++) {
tempData[i + alignmentOffset] &= value[i];
}
if (spi_flash_write(alignedAddress, (uint32_t *)tempData, 4) != SPI_FLASH_RESULT_OK) {
return false;
}
} }
else else
#endif #endif // PUYA_SUPPORT
{ {
rc = spi_flash_write(offset, data, size); uint32_t tempData;
if (spi_flash_read(alignedAddress, &tempData, 4) != SPI_FLASH_RESULT_OK) {
return false;
}
memcpy((uint8_t *)&tempData + alignmentOffset, value, byteCount);
if (spi_flash_write(alignedAddress, &tempData, 4) != SPI_FLASH_RESULT_OK) {
return false;
}
}
return true;
}
size_t EspClass::flashWriteUnalignedMemory(uint32_t address, const uint8_t *data, size_t size) {
size_t sizeLeft = (size & ~3);
size_t currentOffset = 0;
// Memory is unaligned, so we need to copy it to an aligned buffer
uint32_t alignedData[FLASH_PAGE_SIZE / sizeof(uint32_t)] __attribute__((aligned(4)));
// Handle page boundary
bool pageBreak = ((address % 4) != 0) && ((address / FLASH_PAGE_SIZE) != ((address + sizeLeft - 1) / FLASH_PAGE_SIZE));
if (pageBreak) {
size_t byteCount = 4 - (address % 4);
if (!flashReplaceBlock(address, data, byteCount)) {
return 0;
}
// We will now have aligned address, so we can cross page boundaries
currentOffset += byteCount;
// Realign size to 4
sizeLeft = (size - byteCount) & ~3;
}
while (sizeLeft) {
size_t willCopy = std::min(sizeLeft, sizeof(alignedData));
memcpy(alignedData, data + currentOffset, willCopy);
// We now have address, data and size aligned to 4 bytes, so we can use aligned write
if (!flashWrite(address + currentOffset, alignedData, willCopy))
{
return 0;
}
sizeLeft -= willCopy;
currentOffset += willCopy;
}
return currentOffset;
}
bool EspClass::flashWritePageBreak(uint32_t address, const uint8_t *data, size_t size) {
if (size > 4) {
return false;
}
size_t pageLeft = FLASH_PAGE_SIZE - (address % FLASH_PAGE_SIZE);
size_t offset = 0;
size_t sizeLeft = size;
if (pageLeft > 3) {
return false;
}
if (!flashReplaceBlock(address, data, pageLeft)) {
return false;
}
offset += pageLeft;
sizeLeft -= pageLeft;
// We replaced last 4-byte block of the page, now we write the remainder in next page
if (!flashReplaceBlock(address + offset, data + offset, sizeLeft)) {
return false;
}
return true;
}
bool EspClass::flashWrite(uint32_t address, const uint32_t *data, size_t size) {
SpiFlashOpResult rc = SPI_FLASH_RESULT_OK;
bool pageBreak = ((address % 4) != 0 && (address / FLASH_PAGE_SIZE) != ((address + size - 1) / FLASH_PAGE_SIZE));
if ((uintptr_t)data % 4 != 0 || size % 4 != 0 || pageBreak) {
return false;
}
#if PUYA_SUPPORT
if (getFlashChipVendorId() == SPI_FLASH_VENDOR_PUYA) {
rc = spi_flash_write_puya(address, const_cast<uint32_t *>(data), size);
}
else
#endif // PUYA_SUPPORT
{
rc = spi_flash_write(address, const_cast<uint32_t *>(data), size);
} }
return rc == SPI_FLASH_RESULT_OK; return rc == SPI_FLASH_RESULT_OK;
} }
bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size) { bool EspClass::flashWrite(uint32_t address, const uint8_t *data, size_t size) {
auto rc = spi_flash_read(offset, (uint32_t*) data, size); if (size == 0) {
return rc == SPI_FLASH_RESULT_OK; return true;
}
size_t sizeLeft = size & ~3;
size_t currentOffset = 0;
if (sizeLeft) {
if ((uintptr_t)data % 4 != 0) {
size_t written = flashWriteUnalignedMemory(address, data, size);
if (!written) {
return false;
}
currentOffset += written;
sizeLeft -= written;
} else {
bool pageBreak = ((address % 4) != 0 && (address / FLASH_PAGE_SIZE) != ((address + sizeLeft - 1) / FLASH_PAGE_SIZE));
if (pageBreak) {
while (sizeLeft) {
// We cannot cross page boundary, but the write must be 4 byte aligned,
// so this is the maximum amount we can write
size_t pageBoundary = (FLASH_PAGE_SIZE - ((address + currentOffset) % FLASH_PAGE_SIZE)) & ~3;
if (sizeLeft > pageBoundary) {
// Aligned write up to page boundary
if (!flashWrite(address + currentOffset, (uint32_t *)(data + currentOffset), pageBoundary)) {
return false;
}
currentOffset += pageBoundary;
sizeLeft -= pageBoundary;
// Cross the page boundary
if (!flashWritePageBreak(address + currentOffset, data + currentOffset, 4)) {
return false;
}
currentOffset += 4;
sizeLeft -= 4;
} else {
// We do not cross page boundary
if (!flashWrite(address + currentOffset, (uint32_t *)(data + currentOffset), sizeLeft)) {
return false;
}
currentOffset += sizeLeft;
sizeLeft = 0;
}
}
} else {
// Pointer is properly aligned and write does not cross page boundary,
// so use aligned write
if (!flashWrite(address, (uint32_t *)data, sizeLeft)) {
return false;
}
currentOffset = sizeLeft;
sizeLeft = 0;
}
}
}
sizeLeft = size - currentOffset;
if (sizeLeft > 0) {
// Size was not aligned, so we have some bytes left to write, we also need to recheck for
// page boundary crossing
bool pageBreak = ((address % 4) != 0 && (address / FLASH_PAGE_SIZE) != ((address + sizeLeft - 1) / FLASH_PAGE_SIZE));
if (pageBreak) {
// Cross the page boundary
if (!flashWritePageBreak(address + currentOffset, data + currentOffset, sizeLeft)) {
return false;
}
} else {
// Just write partial block
flashReplaceBlock(address + currentOffset, data + currentOffset, sizeLeft);
}
}
return true;
}
bool EspClass::flashRead(uint32_t address, uint8_t *data, size_t size) {
size_t sizeAligned = size & ~3;
size_t currentOffset = 0;
if ((uintptr_t)data % 4 != 0) {
uint32_t alignedData[FLASH_PAGE_SIZE / sizeof(uint32_t)] __attribute__((aligned(4)));
size_t sizeLeft = sizeAligned;
while (sizeLeft) {
size_t willCopy = std::min(sizeLeft, sizeof(alignedData));
// We read to our aligned buffer and then copy to data
if (!flashRead(address + currentOffset, alignedData, willCopy))
{
return false;
}
memcpy(data + currentOffset, alignedData, willCopy);
sizeLeft -= willCopy;
currentOffset += willCopy;
}
} else {
// Pointer is properly aligned, so use aligned read
if (!flashRead(address, (uint32_t *)data, sizeAligned)) {
return false;
}
currentOffset = sizeAligned;
}
if (currentOffset < size) {
uint32_t tempData;
if (spi_flash_read(address + currentOffset, &tempData, 4) != SPI_FLASH_RESULT_OK) {
return false;
}
memcpy((uint8_t *)data + currentOffset, &tempData, size - currentOffset);
}
return true;
}
bool EspClass::flashRead(uint32_t address, uint32_t *data, size_t size) {
if ((uintptr_t)data % 4 != 0 || size % 4 != 0) {
return false;
}
return (spi_flash_read(address, data, size) == SPI_FLASH_RESULT_OK);
} }
String EspClass::getSketchMD5() String EspClass::getSketchMD5()

View File

@ -22,6 +22,7 @@
#define ESP_H #define ESP_H
#include <Arduino.h> #include <Arduino.h>
#include "core_esp8266_features.h"
#include "spi_vendors.h" #include "spi_vendors.h"
/** /**
@ -149,8 +150,48 @@ class EspClass {
bool checkFlashCRC(); bool checkFlashCRC();
bool flashEraseSector(uint32_t sector); bool flashEraseSector(uint32_t sector);
bool flashWrite(uint32_t offset, uint32_t *data, size_t size); /**
bool flashRead(uint32_t offset, uint32_t *data, size_t size); * @brief Write @a size bytes from @a data to flash at @a address
* This overload requires @a data and @a size to be always 4 byte aligned and
* @a address to be 4 byte aligned if the write crossess page boundary,
* but guarantees no overhead (except on PUYA flashes)
* @param address address on flash where write should start, 4 byte alignment is conditional
* @param data input buffer, must be 4-byte aligned
* @param size amount of data, must be a multiple of 4
* @return bool result of operation
* @retval true success
* @retval false failure to write to flash or incorrect alignment of params
*/
bool flashWrite(uint32_t address, const uint32_t *data, size_t size);
/**
* @brief Write @a size bytes from @a data to flash at @a address
* This overload handles all misalignment cases
* @param address address on flash where write should start
* @param data input buffer, passing unaligned memory will cause significant stack usage
* @param size amount of data, passing not multiple of 4 will cause additional reads and writes
* @return bool result of operation
*/
bool flashWrite(uint32_t address, const uint8_t *data, size_t size);
/**
* @brief Read @a size bytes to @a data to flash at @a address
* This overload requires @a data and @a size to be 4 byte aligned
* @param address address on flash where read should start
* @param data input buffer, must be 4-byte aligned
* @param size amount of data, must be a multiple of 4
* @return bool result of operation
* @retval true success
* @retval false failure to read from flash or incorrect alignment of params
*/
bool flashRead(uint32_t address, uint32_t *data, size_t size);
/**
* @brief Read @a size bytes to @a data to flash at @a address
* This overload handles all misalignment cases
* @param address address on flash where read should start
* @param data input buffer, passing unaligned memory will cause significant stack usage
* @param size amount of data, passing not multiple of 4 will cause additional read
* @return bool result of operation
*/
bool flashRead(uint32_t address, uint8_t *data, size_t size);
uint32_t getSketchSize(); uint32_t getSketchSize();
String getSketchMD5(); String getSketchMD5();
@ -174,6 +215,40 @@ class EspClass {
#else #else
uint32_t getCycleCount(); uint32_t getCycleCount();
#endif // !defined(CORE_MOCK) #endif // !defined(CORE_MOCK)
private:
/**
* @brief Replaces @a byteCount bytes of a 4 byte block on flash
*
* @param address flash address
* @param value buffer with data
* @param byteCount number of bytes to replace
* @return bool result of operation
* @retval true success
* @retval false failed to read/write or invalid args
*/
bool flashReplaceBlock(uint32_t address, const uint8_t *value, uint32_t byteCount);
/**
* @brief Write up to @a size bytes from @a data to flash at @a address
* This function takes case of unaligned memory acces by copying @a data to a temporary buffer,
* it also takes care of page boundary crossing see @a flashWritePageBreak as to why it's done.
* Less than @a size bytes may be written, due to 4 byte alignment requirement of spi_flash_write
* @param address address on flash where write should start
* @param data input buffer
* @param size amount of data
* @return size_t amount of data written, 0 on failure
*/
size_t flashWriteUnalignedMemory(uint32_t address, const uint8_t *data, size_t size);
/**
* @brief Splits up to 4 bytes into 4 byte blocks and writes them to flash
* We need this since spi_flash_write cannot handle writing over a page boundary with unaligned offset
* i.e. spi_flash_write(254, data, 4) will fail, also we cannot write less bytes as in
* spi_flash_write(254, data, 2) since it will be extended internally to 4 bytes and fail
* @param address start of write
* @param data data to be written
* @param size amount of data, must be < 4
* @return bool result of operation
*/
bool flashWritePageBreak(uint32_t address, const uint8_t *data, size_t size);
}; };
extern EspClass ESP; extern EspClass ESP;

View File

@ -35,17 +35,15 @@
class Print { class Print {
private: private:
int write_error; int write_error = 0;
template<typename T> size_t printNumber(T n, uint8_t base); template<typename T> size_t printNumber(T n, uint8_t base);
template<typename T, typename... P> inline size_t _println(T v, P... args); template<typename T, typename... P> inline size_t _println(T v, P... args);
protected: protected:
void setWriteError(int err = 1) { void setWriteError(int err = 1) {
write_error = err; write_error = err;
} }
public: public:
Print() : Print() {}
write_error(0) {
}
int getWriteError() { int getWriteError() {
return write_error; return write_error;

View File

@ -37,7 +37,7 @@
class Stream: public Print { class Stream: public Print {
protected: protected:
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read unsigned long _timeout = 1000; // number of milliseconds to wait for the next char before aborting timed read
unsigned long _startMillis; // used for timeout measurement unsigned long _startMillis; // used for timeout measurement
int timedRead(); // private method to read stream with timeout int timedRead(); // private method to read stream with timeout
int timedPeek(); // private method to peek stream with timeout int timedPeek(); // private method to peek stream with timeout
@ -48,9 +48,7 @@ class Stream: public Print {
virtual int read() = 0; virtual int read() = 0;
virtual int peek() = 0; virtual int peek() = 0;
Stream() { Stream() {}
_timeout = 1000;
}
// parsing methods // parsing methods

View File

@ -27,18 +27,6 @@ extern "C" uint32_t _FS_start;
extern "C" uint32_t _FS_end; extern "C" uint32_t _FS_end;
UpdaterClass::UpdaterClass() UpdaterClass::UpdaterClass()
: _async(false)
, _error(0)
, _buffer(0)
, _bufferLen(0)
, _size(0)
, _startAddress(0)
, _currentAddress(0)
, _command(U_FLASH)
, _ledPin(-1)
, _hash(nullptr)
, _verify(nullptr)
, _progress_callback(nullptr)
{ {
#if ARDUINO_SIGNING #if ARDUINO_SIGNING
installSignature(&esp8266::updaterSigningHash, &esp8266::updaterSigningVerifier); installSignature(&esp8266::updaterSigningHash, &esp8266::updaterSigningVerifier);
@ -248,7 +236,7 @@ bool UpdaterClass::end(bool evenIfRemaining){
DEBUG_UPDATER.printf_P(PSTR("[Updater] Adjusted binsize: %d\n"), binSize); DEBUG_UPDATER.printf_P(PSTR("[Updater] Adjusted binsize: %d\n"), binSize);
#endif #endif
// Calculate the MD5 and hash using proper size // Calculate the MD5 and hash using proper size
uint8_t buff[128]; uint8_t buff[128] __attribute__((aligned(4)));
for(int i = 0; i < binSize; i += sizeof(buff)) { for(int i = 0; i < binSize; i += sizeof(buff)) {
ESP.flashRead(_startAddress + i, (uint32_t *)buff, sizeof(buff)); ESP.flashRead(_startAddress + i, (uint32_t *)buff, sizeof(buff));
size_t read = std::min((int)sizeof(buff), binSize - i); size_t read = std::min((int)sizeof(buff), binSize - i);
@ -267,7 +255,7 @@ bool UpdaterClass::end(bool evenIfRemaining){
_reset(); _reset();
return false; return false;
} }
ESP.flashRead(_startAddress + binSize, (uint32_t *)sig, sigLen); ESP.flashRead(_startAddress + binSize, sig, sigLen);
#ifdef DEBUG_UPDATER #ifdef DEBUG_UPDATER
DEBUG_UPDATER.printf_P(PSTR("[Updater] Received Signature:")); DEBUG_UPDATER.printf_P(PSTR("[Updater] Received Signature:"));
for (size_t i=0; i<sigLen; i++) { for (size_t i=0; i<sigLen; i++) {
@ -369,7 +357,7 @@ bool UpdaterClass::_writeBuffer(){
if (eraseResult) { if (eraseResult) {
if(!_async) yield(); if(!_async) yield();
writeResult = ESP.flashWrite(_currentAddress, (uint32_t*) _buffer, _bufferLen); writeResult = ESP.flashWrite(_currentAddress, _buffer, _bufferLen);
} else { // if erase was unsuccessful } else { // if erase was unsuccessful
_currentAddress = (_startAddress + _size); _currentAddress = (_startAddress + _size);
_setError(UPDATE_ERROR_ERASE); _setError(UPDATE_ERROR_ERASE);
@ -447,7 +435,7 @@ bool UpdaterClass::_verifyHeader(uint8_t data) {
bool UpdaterClass::_verifyEnd() { bool UpdaterClass::_verifyEnd() {
if(_command == U_FLASH) { if(_command == U_FLASH) {
uint8_t buf[4]; uint8_t buf[4] __attribute__((aligned(4)));
if(!ESP.flashRead(_startAddress, (uint32_t *) &buf[0], 4)) { if(!ESP.flashRead(_startAddress, (uint32_t *) &buf[0], 4)) {
_currentAddress = (_startAddress); _currentAddress = (_startAddress);
_setError(UPDATE_ERROR_READ); _setError(UPDATE_ERROR_READ);

View File

@ -182,27 +182,27 @@ class UpdaterClass {
void _setError(int error); void _setError(int error);
bool _async; bool _async = false;
uint8_t _error; uint8_t _error = 0;
uint8_t *_buffer; uint8_t *_buffer = nullptr;
size_t _bufferLen; // amount of data written into _buffer size_t _bufferLen = 0; // amount of data written into _buffer
size_t _bufferSize; // total size of _buffer size_t _bufferSize = 0; // total size of _buffer
size_t _size; size_t _size = 0;
uint32_t _startAddress; uint32_t _startAddress = 0;
uint32_t _currentAddress; uint32_t _currentAddress = 0;
uint32_t _command; uint32_t _command = U_FLASH;
String _target_md5; String _target_md5;
MD5Builder _md5; MD5Builder _md5;
int _ledPin; int _ledPin = -1;
uint8_t _ledOn; uint8_t _ledOn;
// Optional signed binary verification // Optional signed binary verification
UpdaterHashClass *_hash; UpdaterHashClass *_hash = nullptr;
UpdaterVerifyClass *_verify; UpdaterVerifyClass *_verify = nullptr;
// Optional progress callback function // Optional progress callback function
THandlerFunction_Progress _progress_callback; THandlerFunction_Progress _progress_callback = nullptr;
}; };
extern UpdaterClass Update; extern UpdaterClass Update;

View File

@ -18,7 +18,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <debug.h>
#include <Arduino.h> #include <Arduino.h>
#include <cxxabi.h> #include <cxxabi.h>

View File

@ -54,6 +54,7 @@
// level 0 will enable ALL interrupts, // level 0 will enable ALL interrupts,
// //
#ifndef CORE_MOCK #ifndef CORE_MOCK
#define xt_rsil(level) (__extension__({uint32_t state; __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state) :: "memory"); state;})) #define xt_rsil(level) (__extension__({uint32_t state; __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state) :: "memory"); state;}))
#define xt_wsr_ps(state) __asm__ __volatile__("wsr %0,ps; isync" :: "a" (state) : "memory") #define xt_wsr_ps(state) __asm__ __volatile__("wsr %0,ps; isync" :: "a" (state) : "memory")
@ -73,6 +74,9 @@ inline uint32_t esp_get_program_counter() {
#else // CORE_MOCK #else // CORE_MOCK
#define xt_rsil(level) (level)
#define xt_wsr_ps(state) do { (void)(state); } while (0)
inline uint32_t esp_get_program_counter() { return 0; } inline uint32_t esp_get_program_counter() { return 0; }
#endif // CORE_MOCK #endif // CORE_MOCK

View File

@ -21,6 +21,9 @@
#ifndef ESP8266_PERI_H_INCLUDED #ifndef ESP8266_PERI_H_INCLUDED
#define ESP8266_PERI_H_INCLUDED #define ESP8266_PERI_H_INCLUDED
// we expect mocking framework to provide these
#ifndef CORE_MOCK
#include "c_types.h" #include "c_types.h"
#include "esp8266_undocumented.h" #include "esp8266_undocumented.h"
@ -847,4 +850,6 @@ extern volatile uint32_t* const esp8266_gpioToFn[16];
**/ **/
#define RANDOM_REG32 ESP8266_DREG(0x20E44) #define RANDOM_REG32 ESP8266_DREG(0x20E44)
#endif // ifndef CORE_MOCK
#endif #endif

View File

@ -28,141 +28,27 @@ extern "C" {
#include "c_types.h" #include "c_types.h"
#include "spi_flash.h" #include "spi_flash.h"
} }
/*
spi_flash_read function requires flash address to be aligned on word boundary.
We take care of this by reading first and last words separately and memcpy
relevant bytes into result buffer.
alignment: 012301230123012301230123
bytes requested: -------***********------
read directly: --------xxxxxxxx--------
read pre: ----aaaa----------------
read post: ----------------bbbb----
alignedBegin: ^
alignedEnd: ^
*/
int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) { int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
optimistic_yield(10000); optimistic_yield(10000);
uint32_t result = FLASH_HAL_OK; // We use flashRead overload that handles proper alignment
uint32_t alignedBegin = (addr + 3) & (~3); if (ESP.flashRead(addr, dst, size)) {
uint32_t alignedEnd = (addr + size) & (~3); return FLASH_HAL_OK;
if (alignedEnd < alignedBegin) { } else {
alignedEnd = alignedBegin; return FLASH_HAL_READ_ERROR;
} }
if (addr < alignedBegin) {
uint32_t nb = alignedBegin - addr;
uint32_t tmp;
if (!ESP.flashRead(alignedBegin - 4, &tmp, 4)) {
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return FLASH_HAL_READ_ERROR;
}
memcpy(dst, ((uint8_t*) &tmp) + 4 - nb, nb);
}
if (alignedEnd != alignedBegin) {
if (!ESP.flashRead(alignedBegin, (uint32_t*) (dst + alignedBegin - addr),
alignedEnd - alignedBegin)) {
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return FLASH_HAL_READ_ERROR;
}
}
if (addr + size > alignedEnd) {
uint32_t nb = addr + size - alignedEnd;
uint32_t tmp;
if (!ESP.flashRead(alignedEnd, &tmp, 4)) {
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return FLASH_HAL_READ_ERROR;
}
memcpy(dst + size - nb, &tmp, nb);
}
return result;
} }
/*
Like spi_flash_read, spi_flash_write has a requirement for flash address to be
aligned. However it also requires RAM address to be aligned as it reads data
in 32-bit words. Flash address (mis-)alignment is handled much the same way
as for reads, but for RAM alignment we have to copy data into a temporary
buffer. The size of this buffer is a tradeoff between number of writes required
and amount of stack required. This is chosen to be 512 bytes here, but might
be adjusted in the future if there are good reasons to do so.
*/
static const int UNALIGNED_WRITE_BUFFER_SIZE = 512;
int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t *src) { int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t *src) {
optimistic_yield(10000); optimistic_yield(10000);
uint32_t alignedBegin = (addr + 3) & (~3); // We use flashWrite overload that handles proper alignment
uint32_t alignedEnd = (addr + size) & (~3); if (ESP.flashWrite(addr, src, size)) {
if (alignedEnd < alignedBegin) { return FLASH_HAL_OK;
alignedEnd = alignedBegin; } else {
return FLASH_HAL_WRITE_ERROR;
} }
if (addr < alignedBegin) {
uint32_t ofs = alignedBegin - addr;
uint32_t nb = (size < ofs) ? size : ofs;
uint8_t tmp[4] __attribute__((aligned(4))) = {0xff, 0xff, 0xff, 0xff};
memcpy(tmp + 4 - ofs, src, nb);
if (!ESP.flashWrite(alignedBegin - 4, (uint32_t*) tmp, 4)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return FLASH_HAL_WRITE_ERROR;
}
}
if (alignedEnd != alignedBegin) {
uint32_t* srcLeftover = (uint32_t*) (src + alignedBegin - addr);
uint32_t srcAlign = ((uint32_t) srcLeftover) & 3;
if (!srcAlign) {
if (!ESP.flashWrite(alignedBegin, (uint32_t*) srcLeftover,
alignedEnd - alignedBegin)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return FLASH_HAL_WRITE_ERROR;
}
}
else {
uint8_t buf[UNALIGNED_WRITE_BUFFER_SIZE];
for (uint32_t sizeLeft = alignedEnd - alignedBegin; sizeLeft; ) {
size_t willCopy = std::min(sizeLeft, sizeof(buf));
memcpy(buf, srcLeftover, willCopy);
if (!ESP.flashWrite(alignedBegin, (uint32_t*) buf, willCopy)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return FLASH_HAL_WRITE_ERROR;
}
sizeLeft -= willCopy;
srcLeftover += willCopy;
alignedBegin += willCopy;
}
}
}
if (addr + size > alignedEnd) {
uint32_t nb = addr + size - alignedEnd;
uint32_t tmp = 0xffffffff;
memcpy(&tmp, src + size - nb, nb);
if (!ESP.flashWrite(alignedEnd, &tmp, 4)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return FLASH_HAL_WRITE_ERROR;
}
}
return FLASH_HAL_OK;
} }
int32_t flash_hal_erase(uint32_t addr, uint32_t size) { int32_t flash_hal_erase(uint32_t addr, uint32_t size) {

View File

@ -127,6 +127,7 @@ void _exit(int status) {
abort(); abort();
} }
int atexit(void (*func)()) __attribute__((weak));
int atexit(void (*func)()) { int atexit(void (*func)()) {
(void) func; (void) func;
return 0; return 0;

View File

@ -127,6 +127,8 @@ int _gettimeofday_r(struct _reent* unused, struct timeval *tp, void *tzp)
void configTime(int timezone_sec, int daylightOffset_sec, const char* server1, const char* server2, const char* server3) void configTime(int timezone_sec, int daylightOffset_sec, const char* server1, const char* server2, const char* server3)
{ {
sntp_stop();
// There is no way to tell when DST starts or stop with this API // There is no way to tell when DST starts or stop with this API
// So DST is always integrated in TZ // So DST is always integrated in TZ
// The other API should be preferred // The other API should be preferred
@ -178,6 +180,8 @@ void configTime(int timezone_sec, int daylightOffset_sec, const char* server1, c
setServer(0, server1); setServer(0, server1);
setServer(1, server2); setServer(1, server2);
setServer(2, server3); setServer(2, server3);
sntp_init();
} }
void setTZ(const char* tz){ void setTZ(const char* tz){

View File

@ -17,9 +17,10 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include <debug.h>
#include <pgmspace.h> #include <pgmspace.h>
#include <esp8266_undocumented.h> #include "../debug.h"
#include "../esp8266_undocumented.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -156,6 +156,39 @@ The Client class creates `clients <https://en.wikipedia.org/wiki/Client_(computi
Check out the separate section with `list of functions <client-class.rst>`__ Check out the separate section with `list of functions <client-class.rst>`__
WiFi Multi
~~~~~~~~~~
`ESP8266WiFiMulti.h` can be used to connect to a WiFi network with strongest WiFi signal (RSSI). This requires registering one or more access points with SSID and password. It automatically switches to another WiFi network when the WiFi connection is lost.
Example:
.. code:: cpp
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti;
// WiFi connect timeout per AP. Increase when connecting takes longer.
const uint32_t connectTimeoutMs = 5000;
void setup()
{
// Set in station mode
WiFi.mode(WIFI_STA);
// Register multi WiFi networks
wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1");
wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");
}
void loop()
{
// Maintain WiFi connection
if (wifiMulti.run(connectTimeoutMs) == WL_CONNECTED) {
...
}
}
BearSSL Client Secure and Server Secure BearSSL Client Secure and Server Secure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -227,8 +260,9 @@ This function returns following codes to describe what is going on with Wi-Fi co
* 0 : ``WL_IDLE_STATUS`` when Wi-Fi is in process of changing between statuses * 0 : ``WL_IDLE_STATUS`` when Wi-Fi is in process of changing between statuses
* 1 : ``WL_NO_SSID_AVAIL``\ in case configured SSID cannot be reached * 1 : ``WL_NO_SSID_AVAIL``\ in case configured SSID cannot be reached
* 3 : ``WL_CONNECTED`` after successful connection is established * 3 : ``WL_CONNECTED`` after successful connection is established
* 4 : ``WL_CONNECT_FAILED`` if password is incorrect * 4 : ``WL_CONNECT_FAILED`` if connection failed
* 6 : ``WL_DISCONNECTED`` if module is not configured in station mode * 6 : ``WL_CONNECT_WRONG_PASSWORD`` if password is incorrect
* 7 : ``WL_DISCONNECTED`` if module is not configured in station mode
It is a good practice to display and check information returned by functions. Application development and troubleshooting will be easier with that. It is a good practice to display and check information returned by functions. Application development and troubleshooting will be easier with that.

View File

@ -251,7 +251,8 @@ Function returns one of the following connection statuses:
- ``WL_CONNECTED`` after successful connection is established - ``WL_CONNECTED`` after successful connection is established
- ``WL_NO_SSID_AVAIL`` in case configured SSID cannot be reached - ``WL_NO_SSID_AVAIL`` in case configured SSID cannot be reached
- ``WL_CONNECT_FAILED`` if password is incorrect - ``WL_CONNECT_FAILED`` if connection failed
- ``WL_CONNECT_WRONG_PASSWORD`` if password is incorrect
- ``WL_IDLE_STATUS`` when Wi-Fi is in process of changing between statuses - ``WL_IDLE_STATUS`` when Wi-Fi is in process of changing between statuses
- ``WL_DISCONNECTED`` if module is not configured in station mode - ``WL_DISCONNECTED`` if module is not configured in station mode
- ``-1`` on timeout - ``-1`` on timeout

View File

@ -571,15 +571,16 @@ Example header data:
:: ::
[HTTP_USER_AGENT] => ESP8266-http-Update [User-Agent] => ESP8266-http-Update
[HTTP_X_ESP8266_STA_MAC] => 18:FE:AA:AA:AA:AA [x-ESP8266-STA-MAC] => 18:FE:AA:AA:AA:AA
[HTTP_X_ESP8266_AP_MAC] => 1A:FE:AA:AA:AA:AA [x-ESP8266-AP-MAC] => 1A:FE:AA:AA:AA:AA
[HTTP_X_ESP8266_FREE_SPACE] => 671744 [x-ESP8266-free-space] => 671744
[HTTP_X_ESP8266_SKETCH_SIZE] => 373940 [x-ESP8266-sketch-size] => 373940
[HTTP_X_ESP8266_SKETCH_MD5] => a56f8ef78a0bebd812f62067daf1408a [x-ESP8266-sketch-md5] => a56f8ef78a0bebd812f62067daf1408a
[HTTP_X_ESP8266_CHIP_SIZE] => 4194304 [x-ESP8266-chip-size] => 4194304
[HTTP_X_ESP8266_SDK_VERSION] => 1.3.0 [x-ESP8266-sdk-version] => 1.3.0
[HTTP_X_ESP8266_VERSION] => DOOR-7-g14f53a19 [x-ESP8266-version] => DOOR-7-g14f53a19
[x-ESP8266-mode] => sketch
With this information the script now can check if an update is needed. It is also possible to deliver different binaries based on the MAC address, as in the following example: With this information the script now can check if an update is needed. It is also possible to deliver different binaries based on the MAC address, as in the following example:
@ -608,20 +609,20 @@ With this information the script now can check if an update is needed. It is als
readfile($path); readfile($path);
} }
if(!check_header('HTTP_USER_AGENT', 'ESP8266-http-Update')) { if(!check_header('User-Agent', 'ESP8266-http-Update')) {
header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403); header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
echo "only for ESP8266 updater!\n"; echo "only for ESP8266 updater!\n";
exit(); exit();
} }
if( if(
!check_header('HTTP_X_ESP8266_STA_MAC') || !check_header('x-ESP8266-STA-MAC') ||
!check_header('HTTP_X_ESP8266_AP_MAC') || !check_header('x-ESP8266-AP-MAC') ||
!check_header('HTTP_X_ESP8266_FREE_SPACE') || !check_header('x-ESP8266-free-space') ||
!check_header('HTTP_X_ESP8266_SKETCH_SIZE') || !check_header('x-ESP8266-sketch-size') ||
!check_header('HTTP_X_ESP8266_SKETCH_MD5') || !check_header('x-ESP8266-sketch-md5') ||
!check_header('HTTP_X_ESP8266_CHIP_SIZE') || !check_header('x-ESP8266-chip-size') ||
!check_header('HTTP_X_ESP8266_SDK_VERSION') !check_header('x-ESP8266-sdk-version')
) { ) {
header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403); header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
echo "only for ESP8266 updater! (header)\n"; echo "only for ESP8266 updater! (header)\n";
@ -633,17 +634,17 @@ With this information the script now can check if an update is needed. It is als
"18:FE:AA:AA:AA:BB" => "TEMP-1.0.0" "18:FE:AA:AA:AA:BB" => "TEMP-1.0.0"
); );
if(!isset($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']])) { if(!isset($db[$_SERVER['x-ESP8266-STA-MAC']])) {
header($_SERVER["SERVER_PROTOCOL"].' 500 ESP MAC not configured for updates', true, 500); header($_SERVER["SERVER_PROTOCOL"].' 500 ESP MAC not configured for updates', true, 500);
} }
$localBinary = "./bin/".$db[$_SERVER['HTTP_X_ESP8266_STA_MAC']].".bin"; $localBinary = "./bin/".$db[$_SERVER['x-ESP8266-STA-MAC']].".bin";
// Check if version has been set and does not match, if not, check if // Check if version has been set and does not match, if not, check if
// MD5 hash between local binary and ESP8266 binary do not match if not. // MD5 hash between local binary and ESP8266 binary do not match if not.
// then no update has been found. // then no update has been found.
if((!check_header('HTTP_X_ESP8266_SDK_VERSION') && $db[$_SERVER['HTTP_X_ESP8266_STA_MAC']] != $_SERVER['HTTP_X_ESP8266_VERSION']) if((!check_header('x-ESP8266-sdk-version') && $db[$_SERVER['x-ESP8266-STA-MAC']] != $_SERVER['x-ESP8266-version'])
|| $_SERVER["HTTP_X_ESP8266_SKETCH_MD5"] != md5_file($localBinary)) { || $_SERVER["x-ESP8266-sketch-md5"] != md5_file($localBinary)) {
sendFile($localBinary); sendFile($localBinary);
} else { } else {
header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304); header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304);

View File

@ -35,17 +35,11 @@ extern "C" uint32_t _EEPROM_start;
EEPROMClass::EEPROMClass(uint32_t sector) EEPROMClass::EEPROMClass(uint32_t sector)
: _sector(sector) : _sector(sector)
, _data(0)
, _size(0)
, _dirty(false)
{ {
} }
EEPROMClass::EEPROMClass(void) EEPROMClass::EEPROMClass(void)
: _sector((((uint32_t)&_EEPROM_start - 0x40200000) / SPI_FLASH_SEC_SIZE)) : _sector((((uint32_t)&_EEPROM_start - 0x40200000) / SPI_FLASH_SEC_SIZE))
, _data(0)
, _size(0)
, _dirty(false)
{ {
} }

View File

@ -68,9 +68,9 @@ public:
protected: protected:
uint32_t _sector; uint32_t _sector;
uint8_t* _data; uint8_t* _data = nullptr;
size_t _size; size_t _size = 0;
bool _dirty; bool _dirty = false;
}; };
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_EEPROM) #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_EEPROM)

View File

@ -47,12 +47,10 @@ extern "C" {
#include "include/UdpContext.h" #include "include/UdpContext.h"
//#define DEBUG_SSDP Serial //#define DEBUG_SSDP Serial
#define SSDP_INTERVAL 1200
#define SSDP_PORT 1900 #define SSDP_PORT 1900
#define SSDP_METHOD_SIZE 10 #define SSDP_METHOD_SIZE 10
#define SSDP_URI_SIZE 2 #define SSDP_URI_SIZE 2
#define SSDP_BUFFER_SIZE 64 #define SSDP_BUFFER_SIZE 64
#define SSDP_MULTICAST_TTL 2
// ssdp ipv6 is FF05::C // ssdp ipv6 is FF05::C
// lwip-v2's igmp_joingroup only supports IPv4 // lwip-v2's igmp_joingroup only supports IPv4
@ -125,19 +123,8 @@ struct SSDPTimer {
ETSTimer timer; ETSTimer timer;
}; };
SSDPClass::SSDPClass() : SSDPClass::SSDPClass()
_server(0), : _respondToAddr(0,0,0,0)
_timer(0),
_port(80),
_ttl(SSDP_MULTICAST_TTL),
_interval(SSDP_INTERVAL),
_respondToAddr(0,0,0,0),
_respondToPort(0),
_pending(false),
_st_is_uuid(false),
_delay(0),
_process_time(0),
_notify_time(0)
{ {
_uuid[0] = '\0'; _uuid[0] = '\0';
_modelNumber[0] = '\0'; _modelNumber[0] = '\0';

View File

@ -46,6 +46,9 @@ class UdpContext;
#define SSDP_MODEL_VERSION_SIZE 32 #define SSDP_MODEL_VERSION_SIZE 32
#define SSDP_MANUFACTURER_SIZE 64 #define SSDP_MANUFACTURER_SIZE 64
#define SSDP_MANUFACTURER_URL_SIZE 128 #define SSDP_MANUFACTURER_URL_SIZE 128
#define SSDP_INTERVAL_SECONDS 1200
#define SSDP_MULTICAST_TTL 2
#define SSDP_HTTP_PORT 80
typedef enum { typedef enum {
NONE, NONE,
@ -101,20 +104,20 @@ class SSDPClass{
void _stopTimer(); void _stopTimer();
static void _onTimerStatic(SSDPClass* self); static void _onTimerStatic(SSDPClass* self);
UdpContext* _server; UdpContext* _server = nullptr;
SSDPTimer* _timer; SSDPTimer* _timer = nullptr;
uint16_t _port; uint16_t _port = SSDP_HTTP_PORT;
uint8_t _ttl; uint8_t _ttl = SSDP_MULTICAST_TTL;
uint32_t _interval; uint32_t _interval = SSDP_INTERVAL_SECONDS;
IPAddress _respondToAddr; IPAddress _respondToAddr;
uint16_t _respondToPort; uint16_t _respondToPort = 0;
bool _pending; bool _pending = false;
bool _st_is_uuid; bool _st_is_uuid = false;
unsigned short _delay; unsigned short _delay = 0;
unsigned long _process_time; unsigned long _process_time = 0;
unsigned long _notify_time; unsigned long _notify_time = 0;
char _schemaURL[SSDP_SCHEMA_URL_SIZE]; char _schemaURL[SSDP_SCHEMA_URL_SIZE];
char _uuid[SSDP_UUID_SIZE]; char _uuid[SSDP_UUID_SIZE];

View File

@ -39,47 +39,12 @@ namespace esp8266webserver {
template <typename ServerType> template <typename ServerType>
ESP8266WebServerTemplate<ServerType>::ESP8266WebServerTemplate(IPAddress addr, int port) ESP8266WebServerTemplate<ServerType>::ESP8266WebServerTemplate(IPAddress addr, int port)
: _server(addr, port) : _server(addr, port)
, _currentMethod(HTTP_ANY)
, _currentVersion(0)
, _currentStatus(HC_NONE)
, _statusChange(0)
, _keepAlive(false)
, _currentHandler(nullptr)
, _firstHandler(nullptr)
, _lastHandler(nullptr)
, _currentArgCount(0)
, _currentArgs(nullptr)
, _currentArgsHavePlain(0)
, _postArgsLen(0)
, _postArgs(nullptr)
, _headerKeysCount(0)
, _currentHeaders(nullptr)
, _contentLength(0)
, _chunked(false)
, _corsEnabled(false)
{ {
} }
template <typename ServerType> template <typename ServerType>
ESP8266WebServerTemplate<ServerType>::ESP8266WebServerTemplate(int port) ESP8266WebServerTemplate<ServerType>::ESP8266WebServerTemplate(int port)
: _server(port) : _server(port)
, _currentMethod(HTTP_ANY)
, _currentVersion(0)
, _currentStatus(HC_NONE)
, _statusChange(0)
, _currentHandler(nullptr)
, _firstHandler(nullptr)
, _lastHandler(nullptr)
, _currentArgCount(0)
, _currentArgs(nullptr)
, _currentArgsHavePlain(0)
, _postArgsLen(0)
, _postArgs(nullptr)
, _headerKeysCount(0)
, _currentHeaders(nullptr)
, _contentLength(0)
, _chunked(false)
, _corsEnabled(false)
{ {
} }

View File

@ -263,35 +263,35 @@ protected:
ServerType _server; ServerType _server;
ClientType _currentClient; ClientType _currentClient;
HTTPMethod _currentMethod; HTTPMethod _currentMethod = HTTP_ANY;
String _currentUri; String _currentUri;
uint8_t _currentVersion; uint8_t _currentVersion = 0;
HTTPClientStatus _currentStatus; HTTPClientStatus _currentStatus = HC_NONE;
unsigned long _statusChange; unsigned long _statusChange = 0;
bool _keepAlive;
RequestHandlerType* _currentHandler; RequestHandlerType* _currentHandler = nullptr;
RequestHandlerType* _firstHandler; RequestHandlerType* _firstHandler = nullptr;
RequestHandlerType* _lastHandler; RequestHandlerType* _lastHandler = nullptr;
THandlerFunction _notFoundHandler; THandlerFunction _notFoundHandler;
THandlerFunction _fileUploadHandler; THandlerFunction _fileUploadHandler;
int _currentArgCount; int _currentArgCount = 0;
RequestArgument* _currentArgs; RequestArgument* _currentArgs = nullptr;
int _currentArgsHavePlain; int _currentArgsHavePlain = 0;
std::unique_ptr<HTTPUpload> _currentUpload; std::unique_ptr<HTTPUpload> _currentUpload;
int _postArgsLen; int _postArgsLen = 0;
RequestArgument* _postArgs; RequestArgument* _postArgs = nullptr;
int _headerKeysCount; int _headerKeysCount = 0;
RequestArgument* _currentHeaders; RequestArgument* _currentHeaders = nullptr;
size_t _contentLength; size_t _contentLength = 0;
String _responseHeaders; String _responseHeaders;
String _hostHeader; String _hostHeader;
bool _chunked; bool _chunked = false;
bool _corsEnabled; bool _corsEnabled = false;
bool _keepAlive = false;
String _snonce; // Store noance and opaque for future comparison String _snonce; // Store noance and opaque for future comparison
String _sopaque; String _sopaque;

View File

@ -21,7 +21,7 @@
#include <memory> #include <memory>
#ifdef DEBUG_ESP_SSL #if defined(DEBUG_ESP_SSL) && defined(DEBUG_ESP_PORT)
#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__) #define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__)
#else #else
#define DEBUG_BSSL(...) #define DEBUG_BSSL(...)

View File

@ -827,15 +827,21 @@ bool ESP8266WiFiGenericClass::resumeFromShutdown (WiFiState* state)
} }
} }
// state->state.fwconfig.bssid is not real bssid (it's what user may have provided when bssid_set==1) // state->state.fwconfig.bssid is not real bssid (it's what user may have provided when bssid_set==1)
if (WiFi.begin((const char*)state->state.fwconfig.ssid, auto beginResult = WiFi.begin((const char*)state->state.fwconfig.ssid,
(const char*)state->state.fwconfig.password, (const char*)state->state.fwconfig.password,
state->state.channel, state->state.channel,
nullptr/*(const uint8_t*)state->state.fwconfig.bssid*/, // <- try with gw's mac address? nullptr/*(const uint8_t*)state->state.fwconfig.bssid*/, // <- try with gw's mac address?
true) == WL_CONNECT_FAILED) true);
if (beginResult == WL_CONNECT_FAILED)
{ {
DEBUG_WIFI("core: resume: WiFi.begin failed\n"); DEBUG_WIFI("core: resume: WiFi.begin failed\n");
return false; return false;
} }
if (beginResult == WL_WRONG_PASSWORD)
{
DEBUG_WIFI("core: resume: WiFi.begin wrong password\n");
return false;
}
} }
if (state->state.mode & WIFI_AP) if (state->state.mode & WIFI_AP)

View File

@ -60,6 +60,9 @@ static void printWiFiStatus(wl_status_t status)
case WL_CONNECT_FAILED: case WL_CONNECT_FAILED:
DEBUG_WIFI_MULTI("[WIFIM] Connecting failed.\n"); DEBUG_WIFI_MULTI("[WIFIM] Connecting failed.\n");
break; break;
case WL_WRONG_PASSWORD:
DEBUG_WIFI_MULTI("[WIFIM] Wrong password.\n");
break;
default: default:
DEBUG_WIFI_MULTI("[WIFIM] Connecting failed (%d).\n", status); DEBUG_WIFI_MULTI("[WIFIM] Connecting failed (%d).\n", status);
break; break;

View File

@ -624,8 +624,9 @@ wl_status_t ESP8266WiFiSTAClass::status() {
case STATION_NO_AP_FOUND: case STATION_NO_AP_FOUND:
return WL_NO_SSID_AVAIL; return WL_NO_SSID_AVAIL;
case STATION_CONNECT_FAIL: case STATION_CONNECT_FAIL:
case STATION_WRONG_PASSWORD:
return WL_CONNECT_FAILED; return WL_CONNECT_FAILED;
case STATION_WRONG_PASSWORD:
return WL_WRONG_PASSWORD;
case STATION_IDLE: case STATION_IDLE:
return WL_IDLE_STATUS; return WL_IDLE_STATUS;
default: default:

View File

@ -59,7 +59,7 @@ extern "C" {
#endif #endif
#ifdef DEBUG_ESP_SSL #if defined(DEBUG_ESP_SSL) && defined(DEBUG_ESP_PORT)
#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__) #define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__)
#else #else
#define DEBUG_BSSL(...) #define DEBUG_BSSL(...)
@ -664,7 +664,7 @@ extern "C" {
if (!xc->done_cert) { if (!xc->done_cert) {
br_sha1_update(&xc->sha1_cert, buf, len); br_sha1_update(&xc->sha1_cert, buf, len);
br_x509_decoder_push(&xc->ctx, (const void*)buf, len); br_x509_decoder_push(&xc->ctx, (const void*)buf, len);
#ifdef DEBUG_ESP_SSL #if defined(DEBUG_ESP_SSL) && defined(DEBUG_ESP_PORT)
DEBUG_BSSL("CERT: "); DEBUG_BSSL("CERT: ");
for (size_t i=0; i<len; i++) { for (size_t i=0; i<len; i++) {
DEBUG_ESP_PORT.printf_P(PSTR("%02x "), buf[i] & 0xff); DEBUG_ESP_PORT.printf_P(PSTR("%02x "), buf[i] & 0xff);

View File

@ -44,18 +44,12 @@ extern "C" {
WiFiServer::WiFiServer(const IPAddress& addr, uint16_t port) WiFiServer::WiFiServer(const IPAddress& addr, uint16_t port)
: _port(port) : _port(port)
, _addr(addr) , _addr(addr)
, _listen_pcb(nullptr)
, _unclaimed(nullptr)
, _discarded(nullptr)
{ {
} }
WiFiServer::WiFiServer(uint16_t port) WiFiServer::WiFiServer(uint16_t port)
: _port(port) : _port(port)
, _addr(IP_ANY_TYPE) , _addr(IP_ANY_TYPE)
, _listen_pcb(nullptr)
, _unclaimed(nullptr)
, _discarded(nullptr)
{ {
} }

View File

@ -70,10 +70,10 @@ class WiFiServer : public Server {
protected: protected:
uint16_t _port; uint16_t _port;
IPAddress _addr; IPAddress _addr;
tcp_pcb* _listen_pcb; tcp_pcb* _listen_pcb = nullptr;
ClientContext* _unclaimed; ClientContext* _unclaimed = nullptr;
ClientContext* _discarded; ClientContext* _discarded = nullptr;
enum { _ndDefault, _ndFalse, _ndTrue } _noDelay = _ndDefault; enum { _ndDefault, _ndFalse, _ndTrue } _noDelay = _ndDefault;
public: public:

View File

@ -55,7 +55,8 @@ typedef enum {
WL_CONNECTED = 3, WL_CONNECTED = 3,
WL_CONNECT_FAILED = 4, WL_CONNECT_FAILED = 4,
WL_CONNECTION_LOST = 5, WL_CONNECTION_LOST = 5,
WL_DISCONNECTED = 6 WL_WRONG_PASSWORD = 6,
WL_DISCONNECTED = 7
} wl_status_t; } wl_status_t;
/* Encryption modes */ /* Encryption modes */

View File

@ -27,7 +27,8 @@
#include "ESP8266mDNS.h" #include "ESP8266mDNS.h"
#include "LEAmDNS_Priv.h" #include "LEAmDNS_Priv.h"
#include <LwipIntf.h> // LwipIntf::stateUpCB()
#include "lwip/igmp.h"
namespace esp8266 namespace esp8266
{ {
@ -61,13 +62,7 @@ MDNSResponder::MDNSResponder(void)
m_pUDPContext(0), m_pUDPContext(0),
m_pcHostname(0), m_pcHostname(0),
m_pServiceQueries(0), m_pServiceQueries(0),
m_fnServiceTxtCallback(0), m_fnServiceTxtCallback(0)
#ifdef ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE
m_bPassivModeEnabled(true),
#else
m_bPassivModeEnabled(false),
#endif
m_netif(nullptr)
{ {
} }
@ -93,104 +88,29 @@ MDNSResponder::~MDNSResponder(void)
Finally the responder is (re)started Finally the responder is (re)started
*/ */
bool MDNSResponder::begin(const char* p_pcHostname, const IPAddress& p_IPAddress, uint32_t p_u32TTL) bool MDNSResponder::begin(const char* p_pcHostname, const IPAddress& /*p_IPAddress*/, uint32_t /*p_u32TTL*/)
{ {
(void)p_u32TTL; // ignored
bool bResult = false; bool bResult = false;
if (0 == m_pUDPContext) if (_setHostname(p_pcHostname))
{ {
if (_setHostname(p_pcHostname)) bResult = _restart();
{
//// select interface
m_netif = nullptr;
IPAddress ipAddress = p_IPAddress;
if (!ipAddress.isSet())
{
IPAddress sta = WiFi.localIP();
IPAddress ap = WiFi.softAPIP();
if (sta.isSet())
{
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] STA interface selected\n")));
ipAddress = sta;
}
else if (ap.isSet())
{
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] AP interface selected\n")));
ipAddress = ap;
}
else
{
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] standard interfaces are not up, please specify one in ::begin()\n")));
return false;
}
// continue to ensure interface is UP
}
// check existence of this IP address in the interface list
bool found = false;
m_netif = nullptr;
for (auto a : addrList)
if (ipAddress == a.addr())
{
if (a.ifUp())
{
found = true;
m_netif = a.interface();
break;
}
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] found interface for IP '%s' but it is not UP\n"), ipAddress.toString().c_str()););
}
if (!found)
{
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] interface defined by IP '%s' not found\n"), ipAddress.toString().c_str()););
return false;
}
//// done selecting the interface
if (m_netif->num == STATION_IF)
{
m_GotIPHandler = WiFi.onStationModeGotIP([this](const WiFiEventStationModeGotIP & pEvent)
{
(void) pEvent;
// Ensure that _restart() runs in USER context
schedule_function([this]()
{
MDNSResponder::_restart();
});
});
m_DisconnectedHandler = WiFi.onStationModeDisconnected([this](const WiFiEventStationModeDisconnected & pEvent)
{
(void) pEvent;
// Ensure that _restart() runs in USER context
schedule_function([this]()
{
MDNSResponder::_restart();
});
});
}
bResult = _restart();
}
DEBUG_EX_ERR(if (!bResult)
{
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] begin: FAILED for '%s'!\n"), (p_pcHostname ? : "-"));
});
} }
else
LwipIntf::stateUpCB
(
[this](netif * intf)
{ {
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] begin: Ignoring multiple calls to begin (Ignored host domain: '%s')!\n"), (p_pcHostname ? : "-"));); (void)intf;
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] new Interface '%c%c' is UP! restarting\n"), intf->name[0], intf->name[1]));
_restart();
} }
);
DEBUG_EX_ERR(if (!bResult)
{
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] begin: FAILED for '%s'!\n"), (p_pcHostname ? : "-"));
});
return bResult; return bResult;
} }
@ -207,9 +127,6 @@ bool MDNSResponder::close(void)
if (0 != m_pUDPContext) if (0 != m_pUDPContext)
{ {
m_GotIPHandler.reset(); // reset WiFi event callbacks.
m_DisconnectedHandler.reset();
_announce(false, true); _announce(false, true);
_resetProbeStatus(false); // Stop probing _resetProbeStatus(false); // Stop probing
_releaseServiceQueries(); _releaseServiceQueries();
@ -1329,11 +1246,6 @@ bool MDNSResponder::notifyAPChange(void)
*/ */
bool MDNSResponder::update(void) bool MDNSResponder::update(void)
{ {
if (m_bPassivModeEnabled)
{
m_bPassivModeEnabled = false;
}
return _process(true); return _process(true);
} }
@ -1374,6 +1286,94 @@ MDNSResponder::hMDNSService MDNSResponder::enableArduino(uint16_t p_u16Port,
return hService; return hService;
} }
/*
MULTICAST GROUPS
*/
/*
MDNSResponder::_joinMulticastGroups
*/
bool MDNSResponder::_joinMulticastGroups(void)
{
bool bResult = false;
// Join multicast group(s)
for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next)
{
if (netif_is_up(pNetIf))
{
#ifdef MDNS_IPV4_SUPPORT
ip_addr_t multicast_addr_V4 = DNS_MQUERY_IPV4_GROUP_INIT;
if (!(pNetIf->flags & NETIF_FLAG_IGMP))
{
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _createHost: Setting flag: flags & NETIF_FLAG_IGMP\n")););
pNetIf->flags |= NETIF_FLAG_IGMP;
if (ERR_OK != igmp_start(pNetIf))
{
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _createHost: igmp_start FAILED!\n")););
}
}
if ((ERR_OK == igmp_joingroup_netif(pNetIf, ip_2_ip4(&multicast_addr_V4))))
{
bResult = true;
}
else
{
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _createHost: igmp_joingroup_netif(" NETIFID_STR ": %s) FAILED!\n"),
NETIFID_VAL(pNetIf), IPAddress(multicast_addr_V4).toString().c_str()););
}
#endif
#ifdef MDNS_IPV6_SUPPORT
ip_addr_t multicast_addr_V6 = DNS_MQUERY_IPV6_GROUP_INIT;
bResult = ((bResult) &&
(ERR_OK == mld6_joingroup_netif(pNetIf, ip_2_ip6(&multicast_addr_V6))));
DEBUG_EX_ERR_IF(!bResult, DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _createHost: mld6_joingroup_netif (" NETIFID_STR ") FAILED!\n"),
NETIFID_VAL(pNetIf)));
#endif
}
}
return bResult;
}
/*
clsLEAmDNS2_Host::_leaveMulticastGroups
*/
bool MDNSResponder::_leaveMulticastGroups()
{
bool bResult = false;
for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next)
{
if (netif_is_up(pNetIf))
{
bResult = true;
// Leave multicast group(s)
#ifdef MDNS_IPV4_SUPPORT
ip_addr_t multicast_addr_V4 = DNS_MQUERY_IPV4_GROUP_INIT;
if (ERR_OK != igmp_leavegroup_netif(pNetIf, ip_2_ip4(&multicast_addr_V4)))
{
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("\n")););
}
#endif
#ifdef MDNS_IPV6_SUPPORT
ip_addr_t multicast_addr_V6 = DNS_MQUERY_IPV6_GROUP_INIT;
if (ERR_OK != mld6_leavegroup_netif(pNetIf, ip_2_ip6(&multicast_addr_V6)/*&(multicast_addr_V6.u_addr.ip6)*/))
{
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("\n")););
}
#endif
}
}
return bResult;
}
} //namespace MDNSImplementation } //namespace MDNSImplementation

View File

@ -164,6 +164,10 @@ namespace MDNSImplementation
*/ */
#define MDNS_QUERYSERVICES_WAIT_TIME 1000 #define MDNS_QUERYSERVICES_WAIT_TIME 1000
/*
Timeout for udpContext->sendtimeout()
*/
#define MDNS_UDPCONTEXT_TIMEOUT 50
/** /**
MDNSResponder MDNSResponder
@ -185,6 +189,8 @@ public:
{ {
return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL); return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL);
} }
bool _joinMulticastGroups(void);
bool _leaveMulticastGroups(void);
// Finish MDNS processing // Finish MDNS processing
bool close(void); bool close(void);
@ -1184,6 +1190,7 @@ protected:
~stcMDNSSendParameter(void); ~stcMDNSSendParameter(void);
bool clear(void); bool clear(void);
bool clearCachedNames(void);
bool shiftOffset(uint16_t p_u16Shift); bool shiftOffset(uint16_t p_u16Shift);
@ -1199,12 +1206,8 @@ protected:
UdpContext* m_pUDPContext; UdpContext* m_pUDPContext;
char* m_pcHostname; char* m_pcHostname;
stcMDNSServiceQuery* m_pServiceQueries; stcMDNSServiceQuery* m_pServiceQueries;
WiFiEventHandler m_DisconnectedHandler;
WiFiEventHandler m_GotIPHandler;
MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback; MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback;
bool m_bPassivModeEnabled;
stcProbeInformation m_HostProbeInformation; stcProbeInformation m_HostProbeInformation;
const netif* m_netif; // network interface to run on
/** CONTROL **/ /** CONTROL **/
/* MAINTENANCE */ /* MAINTENANCE */
@ -1259,11 +1262,6 @@ protected:
uint16_t p_u16QueryType, uint16_t p_u16QueryType,
stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0); stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0);
const IPAddress _getResponseMulticastInterface() const
{
return IPAddress(m_netif->ip_addr);
}
uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader, uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader,
bool* p_pbFullNameMatch = 0) const; bool* p_pbFullNameMatch = 0) const;
uint8_t _replyMaskForService(const stcMDNS_RRHeader& p_RRHeader, uint8_t _replyMaskForService(const stcMDNS_RRHeader& p_RRHeader,

View File

@ -33,7 +33,7 @@
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
#include <lwip/igmp.h> #include <lwip/igmp.h>
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
#include <lwip/mld6.h> #include <lwip/mld6.h>
#endif #endif
@ -172,7 +172,7 @@ const char* clsLEAMDNSHost::clsConsts::pcUDP = "udp";
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
const char* clsLEAMDNSHost::clsConsts::pcReverseIPv4Domain = "in-addr"; const char* clsLEAMDNSHost::clsConsts::pcReverseIPv4Domain = "in-addr";
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
const char* clsLEAMDNSHost::clsConsts::pcReverseIPv6Domain = "ip6"; const char* clsLEAMDNSHost::clsConsts::pcReverseIPv6Domain = "ip6";
#endif #endif
const char* clsLEAMDNSHost::clsConsts::pcReverseTopDomain = "arpa"; const char* clsLEAMDNSHost::clsConsts::pcReverseTopDomain = "arpa";
@ -904,7 +904,7 @@ bool clsLEAMDNSHost::_joinMulticastGroups(void)
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
ip_addr_t multicast_addr_V6 = DNS_MQUERY_IPV6_GROUP_INIT; ip_addr_t multicast_addr_V6 = DNS_MQUERY_IPV6_GROUP_INIT;
bResult = ((bResult) && bResult = ((bResult) &&
(ERR_OK == mld6_joingroup_netif(pNetIf, ip_2_ip6(&multicast_addr_V6)))); (ERR_OK == mld6_joingroup_netif(pNetIf, ip_2_ip6(&multicast_addr_V6))));
@ -937,7 +937,7 @@ bool clsLEAMDNSHost::_leaveMulticastGroups()
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("\n"));); DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("\n")););
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
ip_addr_t multicast_addr_V6 = DNS_MQUERY_IPV6_GROUP_INIT; ip_addr_t multicast_addr_V6 = DNS_MQUERY_IPV6_GROUP_INIT;
if (ERR_OK != mld6_leavegroup_netif(pNetIf, ip_2_ip6(&multicast_addr_V6)/*&(multicast_addr_V6.u_addr.ip6)*/)) if (ERR_OK != mld6_leavegroup_netif(pNetIf, ip_2_ip6(&multicast_addr_V6)/*&(multicast_addr_V6.u_addr.ip6)*/))
{ {

View File

@ -110,7 +110,7 @@
#define MDNS_IPV4_SUPPORT #define MDNS_IPV4_SUPPORT
#if LWIP_IPV6 #if LWIP_IPV6
#define MDNS_IPV6_SUPPORT // If we've got IPv6 support, then we need IPv6 support :-) #define MDNS2_IPV6_SUPPORT // If we've got IPv6 support, then we need IPv6 support :-)
#endif #endif
namespace esp8266 namespace esp8266
@ -136,7 +136,7 @@ protected:
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
static constexpr uint16_t u16IPv4Size = 4; // IPv4 address size in bytes static constexpr uint16_t u16IPv4Size = 4; // IPv4 address size in bytes
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
static constexpr uint16_t u16IPv6Size = 16; // IPv6 address size in bytes static constexpr uint16_t u16IPv6Size = 16; // IPv6 address size in bytes
#endif #endif
static constexpr size_t stServiceTxtMaxLength = 1300; // Maximum length for all service txts for one service static constexpr size_t stServiceTxtMaxLength = 1300; // Maximum length for all service txts for one service
@ -168,7 +168,7 @@ protected:
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
static const char* pcReverseIPv4Domain; // "in-addr"; static const char* pcReverseIPv4Domain; // "in-addr";
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
static const char* pcReverseIPv6Domain; // "ip6"; static const char* pcReverseIPv6Domain; // "ip6";
#endif #endif
static const char* pcReverseTopDomain; // "arpa"; static const char* pcReverseTopDomain; // "arpa";
@ -246,7 +246,7 @@ protected:
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
V4 = 0x01, V4 = 0x01,
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
V6 = 0x02, V6 = 0x02,
#endif #endif
}; };
@ -784,7 +784,7 @@ protected:
bool clear(void); bool clear(void);
}; };
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
/** /**
clsRRAnswerAAAA clsRRAnswerAAAA
*/ */
@ -935,7 +935,7 @@ public:
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
IPv4Address = 0x10, // IPv4 address IPv4Address = 0x10, // IPv4 address
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
IPv6Address = 0x20, // IPv6 address IPv6Address = 0x20, // IPv6 address
#endif #endif
}; };
@ -1004,7 +1004,7 @@ public:
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
clsIPAddressWithTTL::list m_IPv4Addresses; // 3. level answer (A, using host domain), eg. 123.456.789.012 clsIPAddressWithTTL::list m_IPv4Addresses; // 3. level answer (A, using host domain), eg. 123.456.789.012
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
clsIPAddressWithTTL::list m_IPv6Addresses; // 3. level answer (AAAA, using host domain), eg. 1234::09 clsIPAddressWithTTL::list m_IPv6Addresses; // 3. level answer (AAAA, using host domain), eg. 1234::09
#endif #endif
typeQueryAnswerType m_QueryAnswerFlags; // enuQueryAnswerType typeQueryAnswerType m_QueryAnswerFlags; // enuQueryAnswerType
@ -1029,7 +1029,7 @@ public:
const clsIPAddressWithTTL* IPv4AddressAtIndex(uint32_t p_u32Index) const; const clsIPAddressWithTTL* IPv4AddressAtIndex(uint32_t p_u32Index) const;
clsIPAddressWithTTL* IPv4AddressAtIndex(uint32_t p_u32Index); clsIPAddressWithTTL* IPv4AddressAtIndex(uint32_t p_u32Index);
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
bool releaseIPv6Addresses(void); bool releaseIPv6Addresses(void);
bool addIPv6Address(clsIPAddressWithTTL* p_pIPAddress); bool addIPv6Address(clsIPAddressWithTTL* p_pIPAddress);
bool removeIPv6Address(clsIPAddressWithTTL* p_pIPAddress); bool removeIPv6Address(clsIPAddressWithTTL* p_pIPAddress);
@ -1081,7 +1081,7 @@ public:
bool IPv4AddressAvailable(void) const; bool IPv4AddressAvailable(void) const;
clsIPAddressVector IPv4Addresses(void) const; clsIPAddressVector IPv4Addresses(void) const;
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
bool IPv6AddressAvailable(void) const; bool IPv6AddressAvailable(void) const;
clsIPAddressVector IPv6Addresses(void) const; clsIPAddressVector IPv6Addresses(void) const;
#endif #endif
@ -1362,7 +1362,7 @@ protected:
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
bool _processAAnswer(const clsRRAnswerA* p_pAAnswer); bool _processAAnswer(const clsRRAnswerA* p_pAAnswer);
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
bool _processAAAAAnswer(const clsRRAnswerAAAA* p_pAAAAAnswer); bool _processAAAAAnswer(const clsRRAnswerAAAA* p_pAAAAAnswer);
#endif #endif
@ -1426,7 +1426,7 @@ protected:
uint16_t p_u16RDLength); uint16_t p_u16RDLength);
bool _readRRAnswerTXT(clsRRAnswerTXT& p_rRRAnswerTXT, bool _readRRAnswerTXT(clsRRAnswerTXT& p_rRRAnswerTXT,
uint16_t p_u16RDLength); uint16_t p_u16RDLength);
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
bool _readRRAnswerAAAA(clsRRAnswerAAAA& p_rRRAnswerAAAA, bool _readRRAnswerAAAA(clsRRAnswerAAAA& p_rRRAnswerAAAA,
uint16_t p_u16RDLength); uint16_t p_u16RDLength);
#endif #endif
@ -1455,7 +1455,7 @@ protected:
bool _buildDomainForReverseIPv4(IPAddress p_IPv4Address, bool _buildDomainForReverseIPv4(IPAddress p_IPv4Address,
clsRRDomain& p_rReverseIPv4Domain) const; clsRRDomain& p_rReverseIPv4Domain) const;
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
bool _buildDomainForReverseIPv6(IPAddress p_IPv4Address, bool _buildDomainForReverseIPv6(IPAddress p_IPv4Address,
clsRRDomain& p_rReverseIPv6Domain) const; clsRRDomain& p_rReverseIPv6Domain) const;
#endif #endif
@ -1520,7 +1520,7 @@ protected:
clsSendParameter& p_rSendParameter); clsSendParameter& p_rSendParameter);
bool _writeMDNSAnswer_TXT(clsService& p_rService, bool _writeMDNSAnswer_TXT(clsService& p_rService,
clsSendParameter& p_rSendParameter); clsSendParameter& p_rSendParameter);
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
bool _writeMDNSAnswer_AAAA(IPAddress p_IPAddress, bool _writeMDNSAnswer_AAAA(IPAddress p_IPAddress,
clsSendParameter& p_rSendParameter); clsSendParameter& p_rSendParameter);
bool _writeMDNSAnswer_PTR_IPv6(IPAddress p_IPAddress, bool _writeMDNSAnswer_PTR_IPv6(IPAddress p_IPAddress,
@ -1537,7 +1537,7 @@ protected:
bool _writeMDNSAnswer_NSEC_PTR_IPv4(IPAddress p_IPAddress, bool _writeMDNSAnswer_NSEC_PTR_IPv4(IPAddress p_IPAddress,
clsSendParameter& p_rSendParameter); clsSendParameter& p_rSendParameter);
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
bool _writeMDNSAnswer_NSEC_PTR_IPv6(IPAddress p_IPAddress, bool _writeMDNSAnswer_NSEC_PTR_IPv6(IPAddress p_IPAddress,
clsSendParameter& p_rSendParameter); clsSendParameter& p_rSendParameter);
#endif #endif

View File

@ -218,7 +218,7 @@ bool clsLEAMDNSHost::_parseQuery(netif* pNetIf,
(true) (true)
#endif #endif
&& &&
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
(m_pUDPContext->getRemoteAddress().isV6()) && (m_pUDPContext->getRemoteAddress().isV6()) &&
(ip6_addr_islinklocal(ip_2_ip6((const ip_addr_t*)m_pUDPContext->getRemoteAddress()))) (ip6_addr_islinklocal(ip_2_ip6((const ip_addr_t*)m_pUDPContext->getRemoteAddress())))
#else #else
@ -304,7 +304,7 @@ bool clsLEAMDNSHost::_parseQuery(netif* pNetIf,
sendParameter.m_u32HostReplyMask &= ~static_cast<uint32_t>(enuContentFlag::PTR_IPv4); sendParameter.m_u32HostReplyMask &= ~static_cast<uint32_t>(enuContentFlag::PTR_IPv4);
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if (u32HostMatchMask & static_cast<uint32_t>(enuContentFlag::PTR_IPv6)) if (u32HostMatchMask & static_cast<uint32_t>(enuContentFlag::PTR_IPv6))
{ {
// IPv6 PTR was asked for, but is already known -> skipping // IPv6 PTR was asked for, but is already known -> skipping
@ -330,7 +330,7 @@ bool clsLEAMDNSHost::_parseQuery(netif* pNetIf,
else if (u32HostMatchMask & static_cast<uint32_t>(enuContentFlag::AAAA)) else if (u32HostMatchMask & static_cast<uint32_t>(enuContentFlag::AAAA))
{ {
// IPv6 address was asked for // IPv6 address was asked for
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if ((enuAnswerType::AAAA == pKnownRRAnswer->answerType()) && if ((enuAnswerType::AAAA == pKnownRRAnswer->answerType()) &&
(((stcRRAnswerAAAA*)pKnownRRAnswer)->m_IPAddress == _getResponderIPAddress(pNetIf, enuIPProtocolType::V6))) (((stcRRAnswerAAAA*)pKnownRRAnswer)->m_IPAddress == _getResponderIPAddress(pNetIf, enuIPProtocolType::V6)))
{ {
@ -381,7 +381,7 @@ bool clsLEAMDNSHost::_parseQuery(netif* pNetIf,
} }
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if (enuAnswerType::AAAA == pKnownRRAnswer->answerType()) if (enuAnswerType::AAAA == pKnownRRAnswer->answerType())
{ {
IPAddress localIPAddress(_getResponderIPAddress(pNetIf, enuIPProtocolType::V6)); IPAddress localIPAddress(_getResponderIPAddress(pNetIf, enuIPProtocolType::V6));
@ -775,7 +775,7 @@ bool clsLEAMDNSHost::_processAnswers(netif* pNetIf, const clsLEAMDNSHost::clsRRA
bResult = _processAAnswer((clsRRAnswerA*)pRRAnswer); bResult = _processAAnswer((clsRRAnswerA*)pRRAnswer);
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
// AAAA -> IPv6Address // AAAA -> IPv6Address
else if (enuAnswerType::AAAA == pRRAnswer->answerType()) else if (enuAnswerType::AAAA == pRRAnswer->answerType())
{ {
@ -802,7 +802,7 @@ bool clsLEAMDNSHost::_processAnswers(netif* pNetIf, const clsLEAMDNSHost::clsRRA
bPossibleEcho = true; bPossibleEcho = true;
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if ((enuAnswerType::AAAA == pRRAnswer->answerType()) && if ((enuAnswerType::AAAA == pRRAnswer->answerType()) &&
(((clsRRAnswerAAAA*)pRRAnswer)->m_IPAddress == _getResponderIPAddress(pNetIf, enuIPProtocolType::V6))) (((clsRRAnswerAAAA*)pRRAnswer)->m_IPAddress == _getResponderIPAddress(pNetIf, enuIPProtocolType::V6)))
{ {
@ -1159,7 +1159,7 @@ bool clsLEAMDNSHost::_processAAnswer(const clsLEAMDNSHost::clsRRAnswerA* p_pAAns
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
/* /*
clsLEAmDNS2_Host::_processAAAAAnswer (level 3) clsLEAmDNS2_Host::_processAAAAAnswer (level 3)
*/ */
@ -1298,7 +1298,7 @@ bool clsLEAMDNSHost::_updateProbeStatus()
true true
#endif #endif
) || ( ) || (
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
_getResponderIPAddress(pNetIf, enuIPProtocolType::V6).isSet() // OR has IPv6 address _getResponderIPAddress(pNetIf, enuIPProtocolType::V6).isSet() // OR has IPv6 address
#else #else
true true
@ -1511,7 +1511,7 @@ bool clsLEAMDNSHost::_sendHostProbe()
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::A); // Add A answer sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::A); // Add A answer
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::AAAA); // Add AAAA answer sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::AAAA); // Add AAAA answer
#endif #endif
} }
@ -1705,7 +1705,7 @@ bool clsLEAMDNSHost::_announce(bool p_bAnnounce,
sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::A); // A answer sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::A); // A answer
sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::PTR_IPv4); // PTR_IPv4 answer sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::PTR_IPv4); // PTR_IPv4 answer
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::AAAA); // AAAA answer sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::AAAA); // AAAA answer
sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::PTR_IPv6); // PTR_IPv6 answer sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::PTR_IPv6); // PTR_IPv6 answer
#endif #endif
@ -1892,7 +1892,7 @@ bool clsLEAMDNSHost::_checkQueryCache()
pQAnswer->releaseIPv4Addresses(); pQAnswer->releaseIPv4Addresses();
queryAnswerContentFlags |= static_cast<clsQuery::clsAnswer::typeQueryAnswerType>(clsQuery::clsAnswer::enuQueryAnswerType::IPv4Address); queryAnswerContentFlags |= static_cast<clsQuery::clsAnswer::typeQueryAnswerType>(clsQuery::clsAnswer::enuQueryAnswerType::IPv4Address);
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
pQAnswer->releaseIPv6Addresses(); pQAnswer->releaseIPv6Addresses();
queryAnswerContentFlags |= static_cast<clsQuery::clsAnswer::typeQueryAnswerType>(clsQuery::clsAnswer::enuQueryAnswerType::IPv6Address); queryAnswerContentFlags |= static_cast<clsQuery::clsAnswer::typeQueryAnswerType>(clsQuery::clsAnswer::enuQueryAnswerType::IPv6Address);
#endif #endif
@ -1991,7 +1991,7 @@ bool clsLEAMDNSHost::_checkQueryCache()
pQAnswer->removeIPv4Address(pIPv4Address); pQAnswer->removeIPv4Address(pIPv4Address);
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
// IPv6Address (from AAAA) // IPv6Address (from AAAA)
clsQuery::clsAnswer::clsIPAddressWithTTL::list expiredIPv6Addresses; clsQuery::clsAnswer::clsIPAddressWithTTL::list expiredIPv6Addresses;
bool bAAAAUpdateQuerySent = false; bool bAAAAUpdateQuerySent = false;
@ -2095,7 +2095,7 @@ uint32_t clsLEAMDNSHost::_replyMaskForHost(netif* pNetIf,
u32ReplyMask |= static_cast<uint32_t>(enuContentFlag::PTR_IPv4); u32ReplyMask |= static_cast<uint32_t>(enuContentFlag::PTR_IPv4);
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
clsRRDomain reverseIPv6Domain; clsRRDomain reverseIPv6Domain;
if ((_getResponderIPAddress(pNetIf, enuIPProtocolType::V6).isSet()) && if ((_getResponderIPAddress(pNetIf, enuIPProtocolType::V6).isSet()) &&
(_buildDomainForReverseIPv6(_getResponderIPAddress(pNetIf, enuIPProtocolType::V6), reverseIPv6Domain)) && (_buildDomainForReverseIPv6(_getResponderIPAddress(pNetIf, enuIPProtocolType::V6), reverseIPv6Domain)) &&
@ -2121,7 +2121,7 @@ uint32_t clsLEAMDNSHost::_replyMaskForHost(netif* pNetIf,
u32ReplyMask |= static_cast<uint32_t>(enuContentFlag::A); u32ReplyMask |= static_cast<uint32_t>(enuContentFlag::A);
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if ((DNS_RRTYPE_AAAA == p_RRHeader.m_Attributes.m_u16Type) || if ((DNS_RRTYPE_AAAA == p_RRHeader.m_Attributes.m_u16Type) ||
(DNS_RRTYPE_ANY == p_RRHeader.m_Attributes.m_u16Type)) (DNS_RRTYPE_ANY == p_RRHeader.m_Attributes.m_u16Type))
{ {

View File

@ -141,7 +141,7 @@ bool clsLEAMDNSHost::_printRRAnswer(const clsLEAMDNSHost::clsRRAnswer& p_RRAnswe
} }
break; break;
} }
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
case DNS_RRTYPE_AAAA: case DNS_RRTYPE_AAAA:
DEBUG_OUTPUT.printf_P(PSTR("AAAA IP:%s"), ((clsRRAnswerAAAA*&)p_RRAnswer)->m_IPAddress.toString().c_str()); DEBUG_OUTPUT.printf_P(PSTR("AAAA IP:%s"), ((clsRRAnswerAAAA*&)p_RRAnswer)->m_IPAddress.toString().c_str());
break; break;
@ -175,7 +175,7 @@ const char* clsLEAMDNSHost::_RRType2Name(uint16_t p_u16RRType) const
#endif #endif
case DNS_RRTYPE_PTR: strcpy_P(acRRName, PSTR("PTR")); break; case DNS_RRTYPE_PTR: strcpy_P(acRRName, PSTR("PTR")); break;
case DNS_RRTYPE_TXT: strcpy_P(acRRName, PSTR("TXT")); break; case DNS_RRTYPE_TXT: strcpy_P(acRRName, PSTR("TXT")); break;
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
case DNS_RRTYPE_AAAA: strcpy_P(acRRName, PSTR("AAAA")); break; case DNS_RRTYPE_AAAA: strcpy_P(acRRName, PSTR("AAAA")); break;
#endif #endif
case DNS_RRTYPE_SRV: strcpy_P(acRRName, PSTR("SRV")); break; case DNS_RRTYPE_SRV: strcpy_P(acRRName, PSTR("SRV")); break;
@ -288,7 +288,7 @@ const char* clsLEAMDNSHost::_NSECBitmap2String(const clsNSECBitmap* p_pNSECBitma
{ {
strcat_P(acFlagsString, PSTR("PTR ")); // 4 strcat_P(acFlagsString, PSTR("PTR ")); // 4
} }
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if (p_pNSECBitmap->getBit(DNS_RRTYPE_AAAA)) if (p_pNSECBitmap->getBit(DNS_RRTYPE_AAAA))
{ {
strcat_P(acFlagsString, PSTR("AAAA ")); // 5 strcat_P(acFlagsString, PSTR("AAAA ")); // 5

View File

@ -1898,7 +1898,7 @@ bool clsLEAMDNSHost::clsRRAnswerTXT::clear(void)
*/ */
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
/* /*
clsLEAMDNSHost::clsRRAnswerAAAA::clsRRAnswerAAAA constructor clsLEAMDNSHost::clsRRAnswerAAAA::clsRRAnswerAAAA constructor
@ -2398,7 +2398,7 @@ bool clsLEAMDNSHost::clsQuery::clsAnswer::clear(void)
(true) (true)
#endif #endif
&& &&
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
(releaseIPv6Addresses()) (releaseIPv6Addresses())
#else #else
(true) (true)
@ -2528,7 +2528,7 @@ const clsLEAMDNSHost::clsQuery::clsAnswer::clsIPAddressWithTTL* clsLEAMDNSHost::
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
/* /*
clsLEAMDNSHost::clsQuery::clsAnswer::releaseIPv6Addresses clsLEAMDNSHost::clsQuery::clsAnswer::releaseIPv6Addresses
@ -2793,7 +2793,7 @@ clsLEAMDNSHost::clsQuery::clsAnswerAccessor::clsIPAddressVector clsLEAMDNSHost::
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
/* /*
clsLEAMDNSHost::clsQuery::clsAnswerAccessor::IPv6AddressAvailable clsLEAMDNSHost::clsQuery::clsAnswerAccessor::IPv6AddressAvailable
@ -2913,7 +2913,7 @@ size_t clsLEAMDNSHost::clsQuery::clsAnswerAccessor::printTo(Print& p_Print) cons
} }
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if (IPv6AddressAvailable()) if (IPv6AddressAvailable())
{ {
stLen += p_Print.print(cpcI); stLen += p_Print.print(cpcI);

View File

@ -84,7 +84,7 @@ bool clsLEAMDNSHost::_sendMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParamete
DEBUG_OUTPUT.printf_P(PSTR("%s _sendMessage: No IPv4 address available!\n"), _DH()); DEBUG_OUTPUT.printf_P(PSTR("%s _sendMessage: No IPv4 address available!\n"), _DH());
}); });
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
// Only send out IPv6 messages, if we've got an IPv6 address // Only send out IPv6 messages, if we've got an IPv6 address
if (_getResponderIPAddress(pNetIf, enuIPProtocolType::V6).isSet()) if (_getResponderIPAddress(pNetIf, enuIPProtocolType::V6).isSet())
{ {
@ -128,7 +128,7 @@ bool clsLEAMDNSHost::_sendMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParamete
bResult = _sendMessage_Multicast(pNetIf, p_rSendParameter, static_cast<uint8_t>(enuIPProtocolType::V4)); bResult = _sendMessage_Multicast(pNetIf, p_rSendParameter, static_cast<uint8_t>(enuIPProtocolType::V4));
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if (((!ipRemote.isSet()) || // NO remote IP if (((!ipRemote.isSet()) || // NO remote IP
(ipRemote.isV6())) && // OR IPv6 (ipRemote.isV6())) && // OR IPv6
(u8AvailableProtocols & static_cast<uint8_t>(enuIPProtocolType::V6))) // AND IPv6 protocol available (u8AvailableProtocols & static_cast<uint8_t>(enuIPProtocolType::V6))) // AND IPv6 protocol available
@ -182,7 +182,7 @@ bool clsLEAMDNSHost::_sendMessage_Multicast(netif* pNetIf, clsLEAMDNSHost::clsSe
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if (p_IPProtocolTypes & static_cast<uint8_t>(enuIPProtocolType::V6)) if (p_IPProtocolTypes & static_cast<uint8_t>(enuIPProtocolType::V6))
{ {
IPAddress ip6MulticastAddress(DNS_MQUERY_IPV6_GROUP_INIT); IPAddress ip6MulticastAddress(DNS_MQUERY_IPV6_GROUP_INIT);
@ -308,7 +308,7 @@ bool clsLEAMDNSHost::_prepareMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParam
DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P(PSTR("%s _prepareMDNSMessage: _writeMDNSAnswer_PTR_IPv4 FAILED!\n"), _DH());); DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P(PSTR("%s _prepareMDNSMessage: _writeMDNSAnswer_PTR_IPv4 FAILED!\n"), _DH()););
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
// AAAA // AAAA
if ((bResult) && if ((bResult) &&
(p_rSendParameter.m_u32HostReplyMask & static_cast<uint32_t>(enuContentFlag::AAAA)) && (p_rSendParameter.m_u32HostReplyMask & static_cast<uint32_t>(enuContentFlag::AAAA)) &&
@ -383,7 +383,7 @@ bool clsLEAMDNSHost::_prepareMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParam
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
bool bNeedsAdditionalAnswerA = false; bool bNeedsAdditionalAnswerA = false;
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
bool bNeedsAdditionalAnswerAAAA = false; bool bNeedsAdditionalAnswerAAAA = false;
#endif #endif
for (clsService::list::iterator it = m_Services.begin(); ((bResult) && (it != m_Services.end())); it++) for (clsService::list::iterator it = m_Services.begin(); ((bResult) && (it != m_Services.end())); it++)
@ -420,7 +420,7 @@ bool clsLEAMDNSHost::_prepareMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParam
bNeedsAdditionalAnswerA = true; bNeedsAdditionalAnswerA = true;
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if ((bResult) && if ((bResult) &&
(!(p_rSendParameter.m_u32HostReplyMask & static_cast<uint32_t>(enuContentFlag::AAAA)))) // Add IPv6 address (!(p_rSendParameter.m_u32HostReplyMask & static_cast<uint32_t>(enuContentFlag::AAAA)))) // Add IPv6 address
{ {
@ -455,7 +455,7 @@ bool clsLEAMDNSHost::_prepareMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParam
DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P(PSTR("%s _prepareMDNSMessage: _writeMDNSAnswer_A(B) FAILED!\n"), _DH());); DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P(PSTR("%s _prepareMDNSMessage: _writeMDNSAnswer_A(B) FAILED!\n"), _DH()););
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
// Answer AAAA needed? // Answer AAAA needed?
if ((bResult) && if ((bResult) &&
(bNeedsAdditionalAnswerAAAA) && (bNeedsAdditionalAnswerAAAA) &&
@ -481,7 +481,7 @@ bool clsLEAMDNSHost::_prepareMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParam
uint32_t u32NSECContent_PTR_IPv4 = (u32NSECContent & static_cast<uint32_t>(enuContentFlag::PTR_IPv4)); uint32_t u32NSECContent_PTR_IPv4 = (u32NSECContent & static_cast<uint32_t>(enuContentFlag::PTR_IPv4));
u32NSECContent &= ~static_cast<uint32_t>(enuContentFlag::PTR_IPv4); u32NSECContent &= ~static_cast<uint32_t>(enuContentFlag::PTR_IPv4);
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
uint32_t u32NSECContent_PTR_IPv6 = (u32NSECContent & static_cast<uint32_t>(enuContentFlag::PTR_IPv6)); uint32_t u32NSECContent_PTR_IPv6 = (u32NSECContent & static_cast<uint32_t>(enuContentFlag::PTR_IPv6));
u32NSECContent &= ~static_cast<uint32_t>(enuContentFlag::PTR_IPv6); u32NSECContent &= ~static_cast<uint32_t>(enuContentFlag::PTR_IPv6);
#endif #endif
@ -491,7 +491,7 @@ bool clsLEAMDNSHost::_prepareMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParam
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
+ (u32NSECContent_PTR_IPv4 ? 1 : 0) + (u32NSECContent_PTR_IPv4 ? 1 : 0)
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
+ (u32NSECContent_PTR_IPv6 ? 1 : 0) + (u32NSECContent_PTR_IPv6 ? 1 : 0)
#endif #endif
)) ))
@ -504,7 +504,7 @@ bool clsLEAMDNSHost::_prepareMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParam
((!_getResponderIPAddress(pNetIf, (enuIPProtocolType::V4)).isSet()) || ((!_getResponderIPAddress(pNetIf, (enuIPProtocolType::V4)).isSet()) ||
(_writeMDNSAnswer_NSEC_PTR_IPv4(_getResponderIPAddress(pNetIf, (enuIPProtocolType::V4)), p_rSendParameter)))) (_writeMDNSAnswer_NSEC_PTR_IPv4(_getResponderIPAddress(pNetIf, (enuIPProtocolType::V4)), p_rSendParameter))))
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
// Write separate answer for host PTR IPv6 // Write separate answer for host PTR IPv6
&& ((!u32NSECContent_PTR_IPv6) || && ((!u32NSECContent_PTR_IPv6) ||
((!_getResponderIPAddress(pNetIf, (enuIPProtocolType::V6)).isSet()) || ((!_getResponderIPAddress(pNetIf, (enuIPProtocolType::V6)).isSet()) ||
@ -566,7 +566,7 @@ bool clsLEAMDNSHost::_sendQuery(const clsLEAMDNSHost::clsQuery& p_Query,
#ifdef MDNS_IPV4_SUPPORT #ifdef MDNS_IPV4_SUPPORT
bResult = _addQueryRecord(sendParameter, p_Query.m_Domain, DNS_RRTYPE_A); bResult = _addQueryRecord(sendParameter, p_Query.m_Domain, DNS_RRTYPE_A);
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
bResult = _addQueryRecord(sendParameter, p_Query.m_Domain, DNS_RRTYPE_AAAA); bResult = _addQueryRecord(sendParameter, p_Query.m_Domain, DNS_RRTYPE_AAAA);
#endif #endif
break; break;
@ -623,7 +623,7 @@ IPAddress clsLEAMDNSHost::_getResponderIPAddress(netif* pNetIf, enuIPProtocolTyp
ipResponder = netif_ip_addr4(pNetIf); ipResponder = netif_ip_addr4(pNetIf);
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if (enuIPProtocolType::V6 == p_IPProtocolType) if (enuIPProtocolType::V6 == p_IPProtocolType)
{ {
bool bCheckLinkLocal = true; bool bCheckLinkLocal = true;
@ -731,7 +731,7 @@ bool clsLEAMDNSHost::_readRRAnswer(clsLEAMDNSHost::clsRRAnswer*& p_rpRRAnswer)
p_rpRRAnswer = new clsRRAnswerTXT(header, u32TTL); p_rpRRAnswer = new clsRRAnswerTXT(header, u32TTL);
bResult = _readRRAnswerTXT(*(clsRRAnswerTXT*&)p_rpRRAnswer, u16RDLength); bResult = _readRRAnswerTXT(*(clsRRAnswerTXT*&)p_rpRRAnswer, u16RDLength);
break; break;
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
case DNS_RRTYPE_AAAA: case DNS_RRTYPE_AAAA:
p_rpRRAnswer = new clsRRAnswerAAAA(header, u32TTL); p_rpRRAnswer = new clsRRAnswerAAAA(header, u32TTL);
bResult = _readRRAnswerAAAA(*(clsRRAnswerAAAA*&)p_rpRRAnswer, u16RDLength); bResult = _readRRAnswerAAAA(*(clsRRAnswerAAAA*&)p_rpRRAnswer, u16RDLength);
@ -779,7 +779,7 @@ bool clsLEAMDNSHost::_readRRAnswer(clsLEAMDNSHost::clsRRAnswer*& p_rpRRAnswer)
} }
break; break;
} }
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
case DNS_RRTYPE_AAAA: case DNS_RRTYPE_AAAA:
DEBUG_OUTPUT.printf_P(PSTR("AAAA IP:%s"), ((clsRRAnswerAAAA*&)p_rpRRAnswer)->m_IPAddress.toString().c_str()); DEBUG_OUTPUT.printf_P(PSTR("AAAA IP:%s"), ((clsRRAnswerAAAA*&)p_rpRRAnswer)->m_IPAddress.toString().c_str());
break; break;
@ -968,7 +968,7 @@ bool clsLEAMDNSHost::_readRRAnswerTXT(clsLEAMDNSHost::clsRRAnswerTXT& p_rRRAnswe
return bResult; return bResult;
} }
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
bool clsLEAMDNSHost::_readRRAnswerAAAA(clsLEAMDNSHost::clsRRAnswerAAAA& p_rRRAnswerAAAA, bool clsLEAMDNSHost::_readRRAnswerAAAA(clsLEAMDNSHost::clsRRAnswerAAAA& p_rRRAnswerAAAA,
uint16_t p_u16RDLength) uint16_t p_u16RDLength)
{ {
@ -1280,7 +1280,7 @@ bool clsLEAMDNSHost::_buildDomainForReverseIPv4(IPAddress p_IPv4Address,
} }
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
/* /*
MDNSResponder::_buildDomainForReverseIPv6 MDNSResponder::_buildDomainForReverseIPv6
@ -2014,7 +2014,7 @@ bool clsLEAMDNSHost::_writeMDNSAnswer_TXT(clsLEAMDNSHost::clsService& p_rService
return bResult; return bResult;
} }
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
/* /*
MDNSResponder::_writeMDNSAnswer_AAAA MDNSResponder::_writeMDNSAnswer_AAAA
@ -2189,7 +2189,7 @@ clsLEAMDNSHost::clsNSECBitmap* clsLEAMDNSHost::_createNSECBitmap(uint32_t p_u32N
{ {
pNSECBitmap->setBit(DNS_RRTYPE_PTR); // 12/0x0C pNSECBitmap->setBit(DNS_RRTYPE_PTR); // 12/0x0C
} }
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
if (p_u32NSECContent & static_cast<uint32_t>(enuContentFlag::AAAA)) if (p_u32NSECContent & static_cast<uint32_t>(enuContentFlag::AAAA))
{ {
pNSECBitmap->setBit(DNS_RRTYPE_AAAA); // 28/0x1C pNSECBitmap->setBit(DNS_RRTYPE_AAAA); // 28/0x1C
@ -2335,7 +2335,7 @@ bool clsLEAMDNSHost::_writeMDNSAnswer_NSEC_PTR_IPv4(IPAddress p_IPAddress,
#endif #endif
#ifdef MDNS_IPV6_SUPPORT #ifdef MDNS2_IPV6_SUPPORT
/* /*
MDNSResponder::_writeMDNSAnswer_NSEC_PTR_IPv6(host) MDNSResponder::_writeMDNSAnswer_NSEC_PTR_IPv6(host)

View File

@ -85,10 +85,8 @@ bool MDNSResponder::_process(bool p_bUserContext)
} }
else else
{ {
bResult = (m_netif != nullptr) && bResult = _updateProbeStatus() && // Probing
(m_netif->flags & NETIF_FLAG_UP) && // network interface is up and running _checkServiceQueryCache(); // Service query cache check
_updateProbeStatus() && // Probing
_checkServiceQueryCache(); // Service query cache check
} }
return bResult; return bResult;
} }
@ -99,13 +97,10 @@ bool MDNSResponder::_process(bool p_bUserContext)
bool MDNSResponder::_restart(void) bool MDNSResponder::_restart(void)
{ {
return ((m_netif != nullptr) && return ((_resetProbeStatus(true)) && // Stop and restart probing
(m_netif->flags & NETIF_FLAG_UP) && // network interface is up and running
(_resetProbeStatus(true)) && // Stop and restart probing
(_allocUDPContext())); // Restart UDP (_allocUDPContext())); // Restart UDP
} }
/** /**
RECEIVING RECEIVING
*/ */
@ -192,8 +187,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea
{ {
// Define host replies, BUT only answer queries after probing is done // Define host replies, BUT only answer queries after probing is done
u8HostOrServiceReplies = u8HostOrServiceReplies =
sendParameter.m_u8HostReplyMask |= (((m_bPassivModeEnabled) || sendParameter.m_u8HostReplyMask |= (((ProbingStatus_Done == m_HostProbeInformation.m_ProbingStatus))
(ProbingStatus_Done == m_HostProbeInformation.m_ProbingStatus))
? _replyMaskForHost(questionRR.m_Header, 0) ? _replyMaskForHost(questionRR.m_Header, 0)
: 0); : 0);
DEBUG_EX_INFO(if (u8HostOrServiceReplies) DEBUG_EX_INFO(if (u8HostOrServiceReplies)
@ -222,8 +216,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea
for (stcMDNSService* pService = m_pServices; pService; pService = pService->m_pNext) for (stcMDNSService* pService = m_pServices; pService; pService = pService->m_pNext)
{ {
// Define service replies, BUT only answer queries after probing is done // Define service replies, BUT only answer queries after probing is done
uint8_t u8ReplyMaskForQuestion = (((m_bPassivModeEnabled) || uint8_t u8ReplyMaskForQuestion = (((ProbingStatus_Done == pService->m_ProbeInformation.m_ProbingStatus))
(ProbingStatus_Done == pService->m_ProbeInformation.m_ProbingStatus))
? _replyMaskForService(questionRR.m_Header, *pService, 0) ? _replyMaskForService(questionRR.m_Header, *pService, 0)
: 0); : 0);
u8HostOrServiceReplies |= (pService->m_u8ReplyMask |= u8ReplyMaskForQuestion); u8HostOrServiceReplies |= (pService->m_u8ReplyMask |= u8ReplyMaskForQuestion);
@ -364,9 +357,8 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea
// IP4 address was asked for // IP4 address was asked for
#ifdef MDNS_IP4_SUPPORT #ifdef MDNS_IP4_SUPPORT
if ((AnswerType_A == pKnownRRAnswer->answerType()) && if ((AnswerType_A == pKnownRRAnswer->answerType()) &&
(((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == _getResponseMulticastInterface())) (((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == m_pUDPContext->getInputNetif()->ip_addr))
{ {
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: IP4 address already known... skipping!\n"));); DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: IP4 address already known... skipping!\n")););
sendParameter.m_u8HostReplyMask &= ~ContentFlag_A; sendParameter.m_u8HostReplyMask &= ~ContentFlag_A;
} // else: RData NOT IP4 length !! } // else: RData NOT IP4 length !!
@ -399,7 +391,8 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea
#ifdef MDNS_IP4_SUPPORT #ifdef MDNS_IP4_SUPPORT
if (AnswerType_A == pKnownRRAnswer->answerType()) if (AnswerType_A == pKnownRRAnswer->answerType())
{ {
IPAddress localIPAddress(_getResponseMulticastInterface());
IPAddress localIPAddress(m_pUDPContext->getInputNetif()->ip_addr);
if (((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == localIPAddress) if (((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == localIPAddress)
{ {
// SAME IP address -> We've received an old message from ourselfs (same IP) // SAME IP address -> We've received an old message from ourselfs (same IP)
@ -1221,9 +1214,7 @@ bool MDNSResponder::_updateProbeStatus(void)
// //
// Probe host domain // Probe host domain
if ((ProbingStatus_ReadyToStart == m_HostProbeInformation.m_ProbingStatus) && // Ready to get started AND if (ProbingStatus_ReadyToStart == m_HostProbeInformation.m_ProbingStatus)
//TODO: Fix the following to allow Ethernet shield or other interfaces
(_getResponseMulticastInterface() != IPAddress())) // Has IP address
{ {
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Starting host probing...\n"));); DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Starting host probing...\n")););
@ -2007,11 +1998,17 @@ uint8_t MDNSResponder::_replyMaskForHost(const MDNSResponder::stcMDNS_RRHeader&
// PTR request // PTR request
#ifdef MDNS_IP4_SUPPORT #ifdef MDNS_IP4_SUPPORT
stcMDNS_RRDomain reverseIP4Domain; stcMDNS_RRDomain reverseIP4Domain;
if ((_buildDomainForReverseIP4(_getResponseMulticastInterface(), reverseIP4Domain)) && for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next)
(p_RRHeader.m_Domain == reverseIP4Domain))
{ {
// Reverse domain match if (netif_is_up(pNetIf))
u8ReplyMask |= ContentFlag_PTR_IP4; {
if ((_buildDomainForReverseIP4(pNetIf->ip_addr, reverseIP4Domain)) &&
(p_RRHeader.m_Domain == reverseIP4Domain))
{
// Reverse domain match
u8ReplyMask |= ContentFlag_PTR_IP4;
}
}
} }
#endif #endif
#ifdef MDNS_IP6_SUPPORT #ifdef MDNS_IP6_SUPPORT

View File

@ -168,31 +168,23 @@ bool MDNSResponder::_allocUDPContext(void)
{ {
DEBUG_EX_INFO(DEBUG_OUTPUT.println("[MDNSResponder] _allocUDPContext");); DEBUG_EX_INFO(DEBUG_OUTPUT.println("[MDNSResponder] _allocUDPContext"););
bool bResult = false;
_releaseUDPContext(); _releaseUDPContext();
_joinMulticastGroups();
#ifdef MDNS_IP4_SUPPORT m_pUDPContext = new UdpContext;
ip_addr_t multicast_addr = DNS_MQUERY_IPV4_GROUP_INIT; m_pUDPContext->ref();
#endif
#ifdef MDNS_IP6_SUPPORT if (m_pUDPContext->listen(IP4_ADDR_ANY, DNS_MQUERY_PORT))
//TODO: set multicast address (lwip_joingroup() is IPv4 only at the time of writing)
multicast_addr.addr = DNS_MQUERY_IPV6_GROUP_INIT;
#endif
if (ERR_OK == igmp_joingroup(ip_2_ip4(&m_netif->ip_addr), ip_2_ip4(&multicast_addr)))
{ {
m_pUDPContext = new UdpContext; m_pUDPContext->setMulticastTTL(MDNS_MULTICAST_TTL);
m_pUDPContext->ref(); m_pUDPContext->onRx(std::bind(&MDNSResponder::_callProcess, this));
if (m_pUDPContext->listen(IP4_ADDR_ANY, DNS_MQUERY_PORT))
{
m_pUDPContext->setMulticastTTL(MDNS_MULTICAST_TTL);
m_pUDPContext->onRx(std::bind(&MDNSResponder::_callProcess, this));
bResult = m_pUDPContext->connect(&multicast_addr, DNS_MQUERY_PORT);
}
} }
return bResult; else
{
return false;
}
return true;
} }
/* /*
@ -205,6 +197,7 @@ bool MDNSResponder::_releaseUDPContext(void)
{ {
m_pUDPContext->unref(); m_pUDPContext->unref();
m_pUDPContext = 0; m_pUDPContext = 0;
_leaveMulticastGroups();
} }
return true; return true;
} }

View File

@ -2408,12 +2408,25 @@ bool MDNSResponder::stcMDNSSendParameter::clear(void)
delete m_pQuestions; delete m_pQuestions;
m_pQuestions = pNext; m_pQuestions = pNext;
} }
return clearCachedNames();;
}
/*
MDNSResponder::stcMDNSSendParameter::clear cached names
*/
bool MDNSResponder::stcMDNSSendParameter::clearCachedNames(void)
{
m_u16Offset = 0;
while (m_pDomainCacheItems) while (m_pDomainCacheItems)
{ {
stcDomainCacheItem* pNext = m_pDomainCacheItems->m_pNext; stcDomainCacheItem* pNext = m_pDomainCacheItems->m_pNext;
delete m_pDomainCacheItems; delete m_pDomainCacheItems;
m_pDomainCacheItems = pNext; m_pDomainCacheItems = pNext;
} }
m_pDomainCacheItems = nullptr;
return true; return true;
} }

View File

@ -89,8 +89,8 @@ bool MDNSResponder::_sendMDNSMessage(MDNSResponder::stcMDNSSendParameter& p_rSen
}); });
IPAddress ipRemote; IPAddress ipRemote;
ipRemote = m_pUDPContext->getRemoteAddress(); ipRemote = m_pUDPContext->getRemoteAddress();
bResult = ((_prepareMDNSMessage(p_rSendParameter, _getResponseMulticastInterface())) && bResult = ((_prepareMDNSMessage(p_rSendParameter, m_pUDPContext->getInputNetif()->ip_addr)) &&
(m_pUDPContext->send(ipRemote, m_pUDPContext->getRemotePort()))); (m_pUDPContext->sendTimeout(ipRemote, m_pUDPContext->getRemotePort(), MDNS_UDPCONTEXT_TIMEOUT)));
} }
else // Multicast response else // Multicast response
{ {
@ -121,25 +121,32 @@ bool MDNSResponder::_sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParamet
bool bResult = false; bool bResult = false;
IPAddress fromIPAddress; for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next)
fromIPAddress = _getResponseMulticastInterface(); {
m_pUDPContext->setMulticastInterface(fromIPAddress); if (netif_is_up(pNetIf))
{
IPAddress fromIPAddress;
//fromIPAddress = _getResponseMulticastInterface();
fromIPAddress = pNetIf->ip_addr;
m_pUDPContext->setMulticastInterface(fromIPAddress);
#ifdef MDNS_IP4_SUPPORT #ifdef MDNS_IP4_SUPPORT
IPAddress toMulticastAddress(DNS_MQUERY_IPV4_GROUP_INIT); IPAddress toMulticastAddress(DNS_MQUERY_IPV4_GROUP_INIT);
#endif #endif
#ifdef MDNS_IP6_SUPPORT #ifdef MDNS_IP6_SUPPORT
//TODO: set multicast address //TODO: set multicast address
IPAddress toMulticastAddress(DNS_MQUERY_IPV6_GROUP_INIT); IPAddress toMulticastAddress(DNS_MQUERY_IPV6_GROUP_INIT);
#endif #endif
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage_Multicast: Will send to '%s'.\n"), toMulticastAddress.toString().c_str());); DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage_Multicast: Will send to '%s'.\n"), toMulticastAddress.toString().c_str()););
bResult = ((_prepareMDNSMessage(p_rSendParameter, fromIPAddress)) && bResult = ((_prepareMDNSMessage(p_rSendParameter, fromIPAddress)) &&
(m_pUDPContext->send(toMulticastAddress, DNS_MQUERY_PORT))); (m_pUDPContext->sendTimeout(toMulticastAddress, DNS_MQUERY_PORT, MDNS_UDPCONTEXT_TIMEOUT)));
DEBUG_EX_ERR(if (!bResult) DEBUG_EX_ERR(if (!bResult)
{ {
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage_Multicast: FAILED!\n")); DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage_Multicast: FAILED!\n"));
}); });
}
}
return bResult; return bResult;
} }
@ -157,6 +164,7 @@ bool MDNSResponder::_prepareMDNSMessage(MDNSResponder::stcMDNSSendParameter& p_r
{ {
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _prepareMDNSMessage\n"));); DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _prepareMDNSMessage\n")););
bool bResult = true; bool bResult = true;
p_rSendParameter.clearCachedNames(); // Need to remove cached names, p_SendParameter might have been used before on other interface
// Prepare header; count answers // Prepare header; count answers
stcMDNS_MsgHeader msgHeader(p_rSendParameter.m_u16ID, p_rSendParameter.m_bResponse, 0, p_rSendParameter.m_bAuthorative); stcMDNS_MsgHeader msgHeader(p_rSendParameter.m_u16ID, p_rSendParameter.m_bResponse, 0, p_rSendParameter.m_bAuthorative);

View File

@ -42,7 +42,8 @@ void setup() {
"WL_CONNECTED = 3\n" "WL_CONNECTED = 3\n"
"WL_CONNECT_FAILED = 4\n" "WL_CONNECT_FAILED = 4\n"
"WL_CONNECTION_LOST = 5\n" "WL_CONNECTION_LOST = 5\n"
"WL_DISCONNECTED = 6\n" "WL_WRONG_PASSWORD = 6\n"
"WL_DISCONNECTED = 7\n"
); );
} }

View File

@ -0,0 +1,187 @@
#include <BSTest.h>
#include <ESP8266WiFi.h>
BS_ENV_DECLARE();
void preinit() {
// (no C++ in function)
// disable wifi
ESP8266WiFiClass::preinitWiFiOff();
}
void setup()
{
Serial.begin(115200);
BS_RUN(Serial);
}
bool pretest()
{
return true;
}
bool compareBuffers(uint32_t *first, uint32_t *second, size_t offset, size_t len)
{
uint8_t *firstBytes = (uint8_t *)first;
uint8_t *secondBytes = (uint8_t *)second;
for (size_t i = offset; i < offset + len; i++)
{
if (firstBytes[i] != secondBytes[i])
{
Serial.printf("Compare fail @ %u\n", i);
for (size_t j = i & ~3; j < (i & ~3) + 4; j++)
{
Serial.printf("%02x ", firstBytes[j]);
}
Serial.println();
for (size_t j = i & ~3; j < (i & ~3) + 4; j++)
{
Serial.printf("%02x ", secondBytes[j]);
}
Serial.println();
return false;
}
}
return true;
}
bool testFlash(uint32_t start_offset, uint8_t data_offset, size_t amount)
{
static uint32_t *write_buffer = (uint32_t *)malloc(4096);
static uint32_t *read_buffer = (uint32_t *)malloc(4096);
for (uint32_t i = 0; i < 1024; i++)
{
write_buffer[i] = (i + 100) * 33;
read_buffer[i] = 0xAAAAAAAA;
}
Serial.println("---------------------------------------------------");
ESP.flashEraseSector(start_offset / 0x1000);
Serial.printf("Testing %d bytes @ %08x + %d\n", amount, start_offset, data_offset);
unsigned long start = micros();
if (!ESP.flashWrite(start_offset, (uint8_t *)write_buffer + data_offset, amount))
{
Serial.printf("Write fail\n");
return false;
}
if (!ESP.flashRead(start_offset, (uint8_t *)read_buffer + data_offset, amount))
{
Serial.printf("Read fail\n");
return false;
}
if (!compareBuffers(write_buffer, read_buffer, data_offset, amount))
{
return false;
}
Serial.printf("Write took %lu us\n", micros() - start);
return true;
}
// Columns in test case names are as following:
// 1. Offset -> +o (4 byte aligned), -o (unaligned)
// 2. Memory pointer -> +m (4 byte aligned), -m (unaligned)
// 3. Size -> +s (4 byte ), -s (unaligned)
// 4. Number of pages crossed -> np
// Aligned offset
// Aligned memory
// Aligned size
TEST_CASE("|+o|+m|+s|0p|", "[spi_flash]")
{
CHECK(testFlash(0xa0000, 0, 100));
}
TEST_CASE("|+o|+m|+s|1p|", "[spi_flash]")
{
CHECK(testFlash(0xa0000, 0, 512));
}
// Unaligned size
TEST_CASE("|+o|+m|-s|0p|", "[spi_flash]")
{
CHECK(testFlash(0xa0000, 0, 101));
}
TEST_CASE("|+o|+m|-s|2p|", "[spi_flash]")
{
CHECK(testFlash(0xa0000, 0, 515));
}
// Unaligned memory
// Aligned size
TEST_CASE("|+o|-m|+s|0|", "[spi_flash]")
{
CHECK(testFlash(0xa0000, 1, 100));
}
TEST_CASE("|+o|-m|+s|1p|", "[spi_flash]")
{
CHECK(testFlash(0xa0000, 3, 512));
}
// Unaligned size
TEST_CASE("|+o|-m|-s|0p|", "[spi_flash]")
{
CHECK(testFlash(0xa0000, 2, 101));
}
TEST_CASE("|+o|-m|-s|2p|", "[spi_flash]")
{
CHECK(testFlash(0xa0000, 1, 515));
}
// Unaligned offset
// Aligned memory
// Aligned size
TEST_CASE("|-o|+m|+s|0p|", "[spi_flash]")
{
CHECK(testFlash(0xa0001, 0, 100));
}
TEST_CASE("|-o|+m|+s|1p|", "[spi_flash]")
{
CHECK(testFlash(0xa0001, 0, 260));
}
// Unaligned size
TEST_CASE("|-o|+m|-s|0p|", "[spi_flash]")
{
CHECK(testFlash(0xa0001, 0, 105));
}
TEST_CASE("|-o|+m|-s|1p|", "[spi_flash]")
{
CHECK(testFlash(0xa0001, 0, 271));
}
// Unaligned memory
// Aligned size
TEST_CASE("|-o|-m|+s|0p|", "[spi_flash]")
{
CHECK(testFlash(0xa0001, 1, 100));
}
TEST_CASE("|-o|-m|+s|1p|", "[spi_flash]")
{
CHECK(testFlash(0xa0001, 2, 260));
}
// Unaligned size
TEST_CASE("|-o|-m|-s|0p|", "[spi_flash]")
{
CHECK(testFlash(0xa0001, 3, 105));
}
TEST_CASE("|-o|-m|-s|1p|", "[spi_flash]")
{
CHECK(testFlash(0xa0001, 1, 271));
}
TEST_CASE("Last bytes of page", "[spi_flash]")
{
CHECK(testFlash(0xa0000 + 255, 0, 1));
CHECK(testFlash(0xa0000 + 255, 1, 1));
CHECK(testFlash(0xa0000 + 254, 0, 2));
CHECK(testFlash(0xa0000 + 254, 1, 2));
CHECK(testFlash(0xa0000 + 253, 0, 3));
CHECK(testFlash(0xa0000 + 253, 1, 3));
}
TEST_CASE("Unaligned page cross only", "[spi_flash]")
{
CHECK(testFlash(0xa0000 + 254, 0, 3));
CHECK(testFlash(0xa0000 + 254, 1, 3));
CHECK(testFlash(0xa0000 + 255, 0, 2));
CHECK(testFlash(0xa0000 + 255, 1, 2));
}
void loop ()
{
}

View File

@ -0,0 +1,86 @@
/*
Small math example, checking whether we properly integrate with c++ math
ref:
- https://github.com/esp8266/Arduino/issues/5530
- https://github.com/espressif/arduino-esp32/pull/2738
Released to public domain
*/
#include <BSTest.h>
#include <type_traits>
BS_ENV_DECLARE();
void setup()
{
Serial.begin(115200);
BS_RUN(Serial);
}
bool pretest()
{
return true;
}
#define TEST_MATH_IS_SAME(OP1, OP2) \
std::is_same<decltype(OP1), decltype(OP2)>::value
TEST_CASE("std::abs and abs result is the same", "[arduino-math]")
{
CHECK(TEST_MATH_IS_SAME(abs(-5), std::abs(-5)));
CHECK(TEST_MATH_IS_SAME(abs(-25.0), std::abs(-25.0)));
CHECK(TEST_MATH_IS_SAME(abs(10.0), std::abs(10.0)));
CHECK(! TEST_MATH_IS_SAME(abs(10.0), std::abs(10)));
CHECK(! TEST_MATH_IS_SAME(abs(-5), std::abs(10.0)));
}
TEST_CASE("abs works with ints", "[arduino-math]")
{
int a = -3;
int b = 3;
CHECK(TEST_MATH_IS_SAME(abs(a), a));
CHECK(TEST_MATH_IS_SAME(abs(b), b));
CHECK(abs(a) == b);
CHECK(abs(b) == b);
}
template <typename T>
bool compare_floats(T a, T b) {
static_assert(std::is_floating_point<T>::value, "");
return std::fabs(a - b) < std::numeric_limits<float>::epsilon();
}
TEST_CASE("abs works with floats", "[arduino-math]")
{
float a = -3.5;
float b = 3.5;
CHECK(TEST_MATH_IS_SAME(abs(a), a));
CHECK(TEST_MATH_IS_SAME(abs(b), b));
CHECK(compare_floats(abs(a), b));
CHECK(compare_floats(abs(b), b));
}
TEST_CASE("round works with ints", "[arduino-math]")
{
int a = 5;
int b = 10;
CHECK(TEST_MATH_IS_SAME(round(a), std::round(a)));
CHECK(TEST_MATH_IS_SAME(round(b), std::round(b)));
CHECK(compare_floats(round(a), std::round(a)));
CHECK(compare_floats(round(b), std::round(b)));
}
TEST_CASE("round works with floats", "[arduino-math]")
{
float a = 2.9;
float b = 3.0;
CHECK(TEST_MATH_IS_SAME(round(a), a));
CHECK(TEST_MATH_IS_SAME(round(b), b));
CHECK(compare_floats(round(a), b));
CHECK(compare_floats(round(b), b));
}
void loop(){}

View File

@ -174,6 +174,7 @@ FLAGS += -DHTTPCLIENT_1_1_COMPATIBLE=0
FLAGS += -DLWIP_IPV6=0 FLAGS += -DLWIP_IPV6=0
FLAGS += -DHOST_MOCK=1 FLAGS += -DHOST_MOCK=1
FLAGS += -DNONOSDK221=1 FLAGS += -DNONOSDK221=1
FLAGS += -DF_CPU=80000000
FLAGS += $(MKFLAGS) FLAGS += $(MKFLAGS)
FLAGS += -Wimplicit-fallthrough=2 # allow "// fall through" comments to stop spurious warnings FLAGS += -Wimplicit-fallthrough=2 # allow "// fall through" comments to stop spurious warnings
FLAGS += $(USERCFLAGS) FLAGS += $(USERCFLAGS)
@ -267,6 +268,7 @@ ARDUINO_LIBS := \
IPAddress.cpp \ IPAddress.cpp \
Updater.cpp \ Updater.cpp \
base64.cpp \ base64.cpp \
LwipIntfCB.cpp \
) \ ) \
$(addprefix ../../libraries/ESP8266WiFi/src/,\ $(addprefix ../../libraries/ESP8266WiFi/src/,\
ESP8266WiFi.cpp \ ESP8266WiFi.cpp \

View File

@ -1,279 +0,0 @@
/*
Arduino.h - Main include file for the Arduino SDK
Copyright (c) 2005-2013 Arduino Team. All right reserved.
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 Arduino_h
#define Arduino_h
#define MOCK "(mock) "
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <errno.h>
#include "binary.h"
#include "twi.h"
#include "core_esp8266_features.h"
#define HIGH 0x1
#define LOW 0x0
#define PWMRANGE 1023
//GPIO FUNCTIONS
#define INPUT 0x00
#define INPUT_PULLUP 0x02
#define INPUT_PULLDOWN_16 0x04 // PULLDOWN only possible for pin16
#define OUTPUT 0x01
#define OUTPUT_OPEN_DRAIN 0x03
#define WAKEUP_PULLUP 0x05
#define WAKEUP_PULLDOWN 0x07
#define SPECIAL 0xF8 //defaults to the usable BUSes uart0rx/tx uart1tx and hspi
#define FUNCTION_0 0x08
#define FUNCTION_1 0x18
#define FUNCTION_2 0x28
#define FUNCTION_3 0x38
#define FUNCTION_4 0x48
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
#define EULER 2.718281828459045235360287471352
#define SERIAL 0x0
#define DISPLAY 0x1
#define LSBFIRST 0
#define MSBFIRST 1
//Interrupt Modes
#define DISABLED 0x00
#define RISING 0x01
#define FALLING 0x02
#define CHANGE 0x03
#define ONLOW 0x04
#define ONHIGH 0x05
#define ONLOW_WE 0x0C
#define ONHIGH_WE 0x0D
#define DEFAULT 1
#define EXTERNAL 0
//timer dividers
#define TIM_DIV1 0 //80MHz (80 ticks/us - 104857.588 us max)
#define TIM_DIV16 1 //5MHz (5 ticks/us - 1677721.4 us max)
#define TIM_DIV265 3 //312.5Khz (1 tick = 3.2us - 26843542.4 us max)
//timer int_types
#define TIM_EDGE 0
#define TIM_LEVEL 1
//timer reload values
#define TIM_SINGLE 0 //on interrupt routine you need to write a new value to start the timer again
#define TIM_LOOP 1 //on interrupt the counter will start with the same value again
#define timer1_read() (T1V)
#define timer1_enabled() ((T1C & (1 << TCTE)) != 0)
#define timer1_interrupted() ((T1C & (1 << TCIS)) != 0)
typedef void(*timercallback)(void);
void timer1_isr_init(void);
void timer1_enable(uint8_t divider, uint8_t int_type, uint8_t reload);
void timer1_disable(void);
void timer1_attachInterrupt(timercallback userFunc);
void timer1_detachInterrupt(void);
void timer1_write(uint32_t ticks); //maximum ticks 8388607
// timer0 is a special CPU timer that has very high resolution but with
// limited control.
// it uses CCOUNT (ESP.GetCycleCount()) as the non-resetable timer counter
// it does not support divide, type, or reload flags
// it is auto-disabled when the compare value matches CCOUNT
// it is auto-enabled when the compare value changes
#define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM)))
#define timer0_read() ((__extension__({uint32_t count;__asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count));count;})))
#define timer0_write(count) __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory")
void timer0_isr_init(void);
void timer0_attachInterrupt(timercallback userFunc);
void timer0_detachInterrupt(void);
// undefine stdlib's abs if encountered
#ifdef abs
#undef abs
#endif
#define abs(x) ((x)>0?(x):-(x))
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))
void ets_intr_lock();
void ets_intr_unlock();
#ifndef __STRINGIFY
#define __STRINGIFY(a) #a
#endif
#define xt_rsil(level) (level)
#define xt_wsr_ps(state) do { (void)(state); } while (0)
#define interrupts() xt_rsil(0)
#define noInterrupts() xt_rsil(15)
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
// avr-libc defines _NOP() since 1.6.2
#ifndef _NOP
#define _NOP() do { __asm__ volatile ("nop"); } while (0)
#endif
typedef unsigned int word;
#define bit(b) (1UL << (b))
#define _BV(b) (1UL << (b))
typedef uint8_t boolean;
typedef uint8_t byte;
void init(void);
void initVariant(void);
void pinMode(uint8_t pin, uint8_t mode);
void digitalWrite(uint8_t pin, uint8_t val);
int digitalRead(uint8_t pin);
int analogRead(uint8_t pin);
void analogReference(uint8_t mode);
void analogWrite(uint8_t pin, int val);
void analogWriteFreq(uint32_t freq);
void analogWriteRange(uint32_t range);
unsigned long millis(void);
unsigned long micros(void);
void delay(unsigned long);
void delayMicroseconds(unsigned int us);
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
void attachInterrupt(uint8_t pin, void (*)(void), int mode);
void detachInterrupt(uint8_t pin);
void setup(void);
void loop(void);
void yield(void);
void esp_yield(void);
void optimistic_yield(uint32_t interval_us);
#define digitalPinToPort(pin) (0)
#define digitalPinToBitMask(pin) (1UL << (pin))
#define digitalPinToTimer(pin) (0)
#define portOutputRegister(port) ((volatile uint32_t*) &GPO)
#define portInputRegister(port) ((volatile uint32_t*) &GPI)
#define portModeRegister(port) ((volatile uint32_t*) &GPE)
#define NOT_A_PIN -1
#define NOT_A_PORT -1
#define NOT_AN_INTERRUPT -1
#define NOT_ON_TIMER 0
#ifdef __cplusplus
} // extern "C"
#endif
#ifdef __cplusplus
#include <pgmspace.h>
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
#include "Esp.h"
#include "Updater.h"
#include "debug.h"
#if 0
#ifndef _GLIBCXX_VECTOR
// arduino is not compatible with std::vector
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#endif
#endif
#define _min(a,b) ((a)<(b)?(a):(b))
#define _max(a,b) ((a)>(b)?(a):(b))
uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);
#define word(...) makeWord(__VA_ARGS__)
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin);
// WMath prototypes
long random(long);
long random(long, long);
void randomSeed(unsigned long);
long map(long, long, long, long, long);
extern "C" void configTime(long timezone, int daylightOffset_sec,
const char* server1, const char* server2 = nullptr, const char* server3 = nullptr);
#endif
#include "pins_arduino.h"
#endif /* Arduino_h */
#if __cplusplus
#include <WString.h>
#include <map>
#define MOCKARGS 1
extern std::map<String,String> mockArgs;
#endif

View File

@ -56,8 +56,6 @@ const char* fspath = nullptr;
static struct termios initial_settings; static struct termios initial_settings;
std::map<String,String> mockArgs;
int mockverbose (const char* fmt, ...) int mockverbose (const char* fmt, ...)
{ {
va_list ap; va_list ap;
@ -137,8 +135,6 @@ void help (const char* argv0, int exitcode)
"\t-S - spiffs size in KBytes (default: %zd)\n" "\t-S - spiffs size in KBytes (default: %zd)\n"
"\t-L - littlefs size in KBytes (default: %zd)\n" "\t-L - littlefs size in KBytes (default: %zd)\n"
"\t (spiffs, littlefs: negative value will force mismatched size)\n" "\t (spiffs, littlefs: negative value will force mismatched size)\n"
"\t-K - key\n"
"\t-V - value\n"
"\tgeneral:\n" "\tgeneral:\n"
"\t-c - ignore CTRL-C (send it via Serial)\n" "\t-c - ignore CTRL-C (send it via Serial)\n"
"\t-f - no throttle (possibly 100%%CPU)\n" "\t-f - no throttle (possibly 100%%CPU)\n"
@ -162,8 +158,6 @@ static struct option options[] =
{ "spiffskb", required_argument, NULL, 'S' }, { "spiffskb", required_argument, NULL, 'S' },
{ "littlefskb", required_argument, NULL, 'L' }, { "littlefskb", required_argument, NULL, 'L' },
{ "portshifter", required_argument, NULL, 's' }, { "portshifter", required_argument, NULL, 's' },
{ "key", required_argument, NULL, 'K' },
{ "value", required_argument, NULL, 'V' },
{ "once", no_argument, NULL, '1' }, { "once", no_argument, NULL, '1' },
}; };
@ -215,11 +209,10 @@ int main (int argc, char* const argv [])
mock_port_shifter = 0; mock_port_shifter = 0;
else else
mock_port_shifter = MOCK_PORT_SHIFTER; mock_port_shifter = MOCK_PORT_SHIFTER;
String key;
for (;;) for (;;)
{ {
int n = getopt_long(argc, argv, "hlcfbvTi:S:s:L:P:1K:V:", options, NULL); int n = getopt_long(argc, argv, "hlcfbvTi:S:s:L:P:1", options, NULL);
if (n < 0) if (n < 0)
break; break;
switch (n) switch (n)
@ -260,12 +253,6 @@ int main (int argc, char* const argv [])
case 'T': case 'T':
serial_timestamp = true; serial_timestamp = true;
break; break;
case 'K':
key = optarg;
break;
case 'V':
mockArgs[key] = optarg;
break;
case '1': case '1':
run_once = true; run_once = true;
break; break;

View File

@ -159,7 +159,15 @@ FlashMode_t EspClass::magicFlashChipMode(uint8_t byte)
return FM_DOUT; return FM_DOUT;
} }
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) bool EspClass::flashWrite(uint32_t offset, const uint32_t *data, size_t size)
{
(void)offset;
(void)data;
(void)size;
return true;
}
bool EspClass::flashWrite(uint32_t offset, const uint8_t *data, size_t size)
{ {
(void)offset; (void)offset;
(void)data; (void)data;
@ -175,6 +183,14 @@ bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size)
return true; return true;
} }
bool EspClass::flashRead(uint32_t offset, uint8_t *data, size_t size)
{
(void)offset;
(void)data;
(void)size;
return true;
}
uint32_t EspClass::magicFlashChipSize(uint8_t byte) { uint32_t EspClass::magicFlashChipSize(uint8_t byte) {
switch(byte & 0x0F) { switch(byte & 0x0F) {
case 0x0: // 4 Mbit (512KB) case 0x0: // 4 Mbit (512KB)

View File

@ -53,16 +53,6 @@ int ets_printf (const char* fmt, ...)
return len; return len;
} }
extern "C" void configTime(long timezone, int daylightOffset_sec,
const char* server1, const char* server2, const char* server3)
{
(void)server1;
(void)server2;
(void)server3;
mockverbose("configTime: TODO (tz=%ldH offset=%dS) (time will be host's)\n", timezone, daylightOffset_sec);
}
void stack_thunk_add_ref() { } void stack_thunk_add_ref() { }
void stack_thunk_del_ref() { } void stack_thunk_del_ref() { }
void stack_thunk_repaint() { } void stack_thunk_repaint() { }
@ -78,3 +68,13 @@ void stack_thunk_dump_stack() { }
#define make_stack_thunk(fcnToThunk) #define make_stack_thunk(fcnToThunk)
}; };
void configTime(int timezone, int daylightOffset_sec,
const char* server1, const char* server2, const char* server3)
{
(void)server1;
(void)server2;
(void)server3;
mockverbose("configTime: TODO (tz=%dH offset=%dS) (time will be host's)\n", timezone, daylightOffset_sec);
}

View File

@ -31,6 +31,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <cerrno>
#include "flash_hal_mock.h" #include "flash_hal_mock.h"
#define LITTLEFS_FILE_NAME "littlefs.bin" #define LITTLEFS_FILE_NAME "littlefs.bin"

View File

@ -30,6 +30,7 @@
*/ */
#define CORE_MOCK 1 #define CORE_MOCK 1
#define MOCK "(mock) " // TODO: provide common logging API instead of adding this string everywhere?
// //
@ -37,7 +38,6 @@
#define ESP8266 1 #define ESP8266 1
#define A0 0 #define A0 0
#define LED_BUILTIN 0 #define LED_BUILTIN 0
#define F_CPU 80000000
#define LWIP_OPEN_SRC #define LWIP_OPEN_SRC
#define TCP_MSS 536 #define TCP_MSS 536
#define LWIP_FEATURES 1 #define LWIP_FEATURES 1
@ -54,28 +54,23 @@
#define D7 7 #define D7 7
#define D8 8 #define D8 8
// include host's STL before any other include file
// because core definition like max() is in the way
#ifdef __cplusplus
#include <vector>
#endif
#include <stddef.h> #include <stddef.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//#include <stdlib_noniso.h> // TODO: #include <stdlib_noniso.h> ?
char* itoa (int val, char *s, int radix); char* itoa (int val, char *s, int radix);
char* ltoa (long val, char *s, int radix); char* ltoa (long val, char *s, int radix);
#ifdef __cplusplus
}
#endif
size_t strlcat(char *dst, const char *src, size_t size); size_t strlcat(char *dst, const char *src, size_t size);
size_t strlcpy(char *dst, const char *src, size_t size); size_t strlcpy(char *dst, const char *src, size_t size);
#ifdef __cplusplus
}
#endif
// exotic typedefs used in the sdk // exotic typedefs used in the sdk
#include <stdint.h> #include <stdint.h>
@ -91,9 +86,6 @@ uint32_t esp_get_cycle_count();
#include <Arduino.h> #include <Arduino.h>
//
#include <stdlib.h>
#define RANDOM_REG32 ((uint32_t)random()) #define RANDOM_REG32 ((uint32_t)random())
// net tweak // net tweak

View File

@ -26,6 +26,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <cerrno>
#include "flash_hal_mock.h" #include "flash_hal_mock.h"

View File

@ -7,6 +7,7 @@
#define FLASH_SECTOR_SIZE 0x1000 #define FLASH_SECTOR_SIZE 0x1000
#define FLASH_BLOCK_SIZE 0x10000 #define FLASH_BLOCK_SIZE 0x10000
#define FLASH_PAGE_SIZE 0x100
#define APP_START_OFFSET 0x1000 #define APP_START_OFFSET 0x1000
//pulled this define from spi_flash.h for reuse in the Arduino core without pulling in a bunch of other stuff //pulled this define from spi_flash.h for reuse in the Arduino core without pulling in a bunch of other stuff

View File

@ -74,6 +74,13 @@ def main():
outdir = os.path.dirname(args.out) outdir = os.path.dirname(args.out)
if not os.path.exists(outdir): if not os.path.exists(outdir):
os.makedirs(outdir) os.makedirs(outdir)
try:
with open(args.out, "r") as inp:
old_val = inp.read()
if old_val == val:
return
except Exception:
pass
with open(args.out, "w") as f: with open(args.out, "w") as f:
f.write(val) f.write(val)
return 0 return 0