mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
Merge branch 'master' into feature/issue-2246-multi-wifi-hidden
This commit is contained in:
commit
00673e05fb
@ -37,6 +37,7 @@ extern "C" {
|
||||
#include "binary.h"
|
||||
#include "esp8266_peri.h"
|
||||
#include "twi.h"
|
||||
|
||||
#include "core_esp8266_features.h"
|
||||
#include "core_esp8266_version.h"
|
||||
|
||||
@ -125,15 +126,11 @@ void timer0_isr_init(void);
|
||||
void timer0_attachInterrupt(timercallback userFunc);
|
||||
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 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();
|
||||
|
||||
#define interrupts() xt_rsil(0)
|
||||
#define noInterrupts() xt_rsil(15)
|
||||
|
||||
@ -162,11 +159,12 @@ typedef uint16_t word;
|
||||
typedef bool boolean;
|
||||
typedef uint8_t byte;
|
||||
|
||||
void ets_intr_lock();
|
||||
void ets_intr_unlock();
|
||||
|
||||
void init(void);
|
||||
void initVariant(void);
|
||||
|
||||
int atexit(void (*func)()) __attribute__((weak));
|
||||
|
||||
void pinMode(uint8_t pin, uint8_t mode);
|
||||
void digitalWrite(uint8_t pin, uint8_t val);
|
||||
int digitalRead(uint8_t pin);
|
||||
@ -212,21 +210,20 @@ void optimistic_yield(uint32_t interval_us);
|
||||
} // extern "C"
|
||||
#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
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#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::max;
|
||||
@ -234,6 +231,10 @@ using std::round;
|
||||
using std::isinf;
|
||||
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 _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);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
#include "debug.h"
|
||||
#include "pins_arduino.h"
|
||||
|
||||
#endif
|
||||
|
@ -26,7 +26,9 @@
|
||||
#include "MD5Builder.h"
|
||||
#include "umm_malloc/umm_malloc.h"
|
||||
#include "cont.h"
|
||||
|
||||
#include "coredecls.h"
|
||||
#include <pgmspace.h>
|
||||
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
@ -40,11 +42,6 @@ extern struct rst_info resetInfo;
|
||||
#ifndef PUYA_SUPPORT
|
||||
#define PUYA_SUPPORT 1
|
||||
#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
|
||||
@ -666,11 +663,14 @@ static SpiFlashOpResult spi_flash_write_puya(uint32_t offset, uint32_t *data, si
|
||||
if (data == nullptr) {
|
||||
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.
|
||||
static uint32_t *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.
|
||||
if (flash_write_puya_buf == nullptr) {
|
||||
// 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;
|
||||
while (bytesLeft > 0 && rc == SPI_FLASH_RESULT_OK) {
|
||||
size_t bytesNow = bytesLeft;
|
||||
if (bytesNow > PUYA_BUFFER_SIZE) {
|
||||
bytesNow = PUYA_BUFFER_SIZE;
|
||||
bytesLeft -= PUYA_BUFFER_SIZE;
|
||||
if (bytesNow > FLASH_PAGE_SIZE) {
|
||||
bytesNow = FLASH_PAGE_SIZE;
|
||||
bytesLeft -= FLASH_PAGE_SIZE;
|
||||
} else {
|
||||
bytesLeft = 0;
|
||||
}
|
||||
size_t bytesAligned = (bytesNow + 3) & ~3;
|
||||
rc = spi_flash_read(pos, flash_write_puya_buf, bytesAligned);
|
||||
rc = spi_flash_read(pos, flash_write_puya_buf, bytesNow);
|
||||
if (rc != SPI_FLASH_RESULT_OK) {
|
||||
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;
|
||||
++ptr;
|
||||
}
|
||||
rc = spi_flash_write(pos, flash_write_puya_buf, bytesAligned);
|
||||
rc = spi_flash_write(pos, flash_write_puya_buf, bytesNow);
|
||||
pos += bytesNow;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) {
|
||||
SpiFlashOpResult rc = SPI_FLASH_RESULT_OK;
|
||||
bool EspClass::flashReplaceBlock(uint32_t address, const uint8_t *value, uint32_t byteCount) {
|
||||
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 (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
|
||||
#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;
|
||||
}
|
||||
|
||||
bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size) {
|
||||
auto rc = spi_flash_read(offset, (uint32_t*) data, size);
|
||||
return rc == SPI_FLASH_RESULT_OK;
|
||||
bool EspClass::flashWrite(uint32_t address, const uint8_t *data, size_t size) {
|
||||
if (size == 0) {
|
||||
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()
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define ESP_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "core_esp8266_features.h"
|
||||
#include "spi_vendors.h"
|
||||
|
||||
/**
|
||||
@ -149,8 +150,48 @@ class EspClass {
|
||||
bool checkFlashCRC();
|
||||
|
||||
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();
|
||||
String getSketchMD5();
|
||||
@ -174,6 +215,40 @@ class EspClass {
|
||||
#else
|
||||
uint32_t getCycleCount();
|
||||
#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;
|
||||
|
@ -35,17 +35,15 @@
|
||||
|
||||
class Print {
|
||||
private:
|
||||
int write_error;
|
||||
int write_error = 0;
|
||||
template<typename T> size_t printNumber(T n, uint8_t base);
|
||||
template<typename T, typename... P> inline size_t _println(T v, P... args);
|
||||
protected:
|
||||
protected:
|
||||
void setWriteError(int err = 1) {
|
||||
write_error = err;
|
||||
}
|
||||
public:
|
||||
Print() :
|
||||
write_error(0) {
|
||||
}
|
||||
Print() {}
|
||||
|
||||
int getWriteError() {
|
||||
return write_error;
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
class Stream: public Print {
|
||||
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
|
||||
int timedRead(); // private method to read 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 peek() = 0;
|
||||
|
||||
Stream() {
|
||||
_timeout = 1000;
|
||||
}
|
||||
Stream() {}
|
||||
|
||||
// parsing methods
|
||||
|
||||
|
@ -27,18 +27,6 @@ extern "C" uint32_t _FS_start;
|
||||
extern "C" uint32_t _FS_end;
|
||||
|
||||
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
|
||||
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);
|
||||
#endif
|
||||
// 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)) {
|
||||
ESP.flashRead(_startAddress + i, (uint32_t *)buff, sizeof(buff));
|
||||
size_t read = std::min((int)sizeof(buff), binSize - i);
|
||||
@ -267,7 +255,7 @@ bool UpdaterClass::end(bool evenIfRemaining){
|
||||
_reset();
|
||||
return false;
|
||||
}
|
||||
ESP.flashRead(_startAddress + binSize, (uint32_t *)sig, sigLen);
|
||||
ESP.flashRead(_startAddress + binSize, sig, sigLen);
|
||||
#ifdef DEBUG_UPDATER
|
||||
DEBUG_UPDATER.printf_P(PSTR("[Updater] Received Signature:"));
|
||||
for (size_t i=0; i<sigLen; i++) {
|
||||
@ -369,7 +357,7 @@ bool UpdaterClass::_writeBuffer(){
|
||||
|
||||
if (eraseResult) {
|
||||
if(!_async) yield();
|
||||
writeResult = ESP.flashWrite(_currentAddress, (uint32_t*) _buffer, _bufferLen);
|
||||
writeResult = ESP.flashWrite(_currentAddress, _buffer, _bufferLen);
|
||||
} else { // if erase was unsuccessful
|
||||
_currentAddress = (_startAddress + _size);
|
||||
_setError(UPDATE_ERROR_ERASE);
|
||||
@ -447,7 +435,7 @@ bool UpdaterClass::_verifyHeader(uint8_t data) {
|
||||
bool UpdaterClass::_verifyEnd() {
|
||||
if(_command == U_FLASH) {
|
||||
|
||||
uint8_t buf[4];
|
||||
uint8_t buf[4] __attribute__((aligned(4)));
|
||||
if(!ESP.flashRead(_startAddress, (uint32_t *) &buf[0], 4)) {
|
||||
_currentAddress = (_startAddress);
|
||||
_setError(UPDATE_ERROR_READ);
|
||||
|
@ -182,27 +182,27 @@ class UpdaterClass {
|
||||
|
||||
void _setError(int error);
|
||||
|
||||
bool _async;
|
||||
uint8_t _error;
|
||||
uint8_t *_buffer;
|
||||
size_t _bufferLen; // amount of data written into _buffer
|
||||
size_t _bufferSize; // total size of _buffer
|
||||
size_t _size;
|
||||
uint32_t _startAddress;
|
||||
uint32_t _currentAddress;
|
||||
uint32_t _command;
|
||||
bool _async = false;
|
||||
uint8_t _error = 0;
|
||||
uint8_t *_buffer = nullptr;
|
||||
size_t _bufferLen = 0; // amount of data written into _buffer
|
||||
size_t _bufferSize = 0; // total size of _buffer
|
||||
size_t _size = 0;
|
||||
uint32_t _startAddress = 0;
|
||||
uint32_t _currentAddress = 0;
|
||||
uint32_t _command = U_FLASH;
|
||||
|
||||
String _target_md5;
|
||||
MD5Builder _md5;
|
||||
|
||||
int _ledPin;
|
||||
int _ledPin = -1;
|
||||
uint8_t _ledOn;
|
||||
|
||||
// Optional signed binary verification
|
||||
UpdaterHashClass *_hash;
|
||||
UpdaterVerifyClass *_verify;
|
||||
UpdaterHashClass *_hash = nullptr;
|
||||
UpdaterVerifyClass *_verify = nullptr;
|
||||
// Optional progress callback function
|
||||
THandlerFunction_Progress _progress_callback;
|
||||
THandlerFunction_Progress _progress_callback = nullptr;
|
||||
};
|
||||
|
||||
extern UpdaterClass Update;
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <Arduino.h>
|
||||
#include <cxxabi.h>
|
||||
|
||||
|
@ -54,6 +54,7 @@
|
||||
// level 0 will enable ALL interrupts,
|
||||
//
|
||||
#ifndef CORE_MOCK
|
||||
|
||||
#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")
|
||||
|
||||
@ -73,6 +74,9 @@ inline uint32_t esp_get_program_counter() {
|
||||
|
||||
#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; }
|
||||
|
||||
#endif // CORE_MOCK
|
||||
|
@ -21,6 +21,9 @@
|
||||
#ifndef ESP8266_PERI_H_INCLUDED
|
||||
#define ESP8266_PERI_H_INCLUDED
|
||||
|
||||
// we expect mocking framework to provide these
|
||||
#ifndef CORE_MOCK
|
||||
|
||||
#include "c_types.h"
|
||||
#include "esp8266_undocumented.h"
|
||||
|
||||
@ -847,4 +850,6 @@ extern volatile uint32_t* const esp8266_gpioToFn[16];
|
||||
**/
|
||||
#define RANDOM_REG32 ESP8266_DREG(0x20E44)
|
||||
|
||||
#endif // ifndef CORE_MOCK
|
||||
|
||||
#endif
|
||||
|
@ -28,141 +28,27 @@ extern "C" {
|
||||
#include "c_types.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) {
|
||||
optimistic_yield(10000);
|
||||
|
||||
uint32_t result = FLASH_HAL_OK;
|
||||
uint32_t alignedBegin = (addr + 3) & (~3);
|
||||
uint32_t alignedEnd = (addr + size) & (~3);
|
||||
if (alignedEnd < alignedBegin) {
|
||||
alignedEnd = alignedBegin;
|
||||
// We use flashRead overload that handles proper alignment
|
||||
if (ESP.flashRead(addr, dst, size)) {
|
||||
return FLASH_HAL_OK;
|
||||
} else {
|
||||
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) {
|
||||
optimistic_yield(10000);
|
||||
|
||||
uint32_t alignedBegin = (addr + 3) & (~3);
|
||||
uint32_t alignedEnd = (addr + size) & (~3);
|
||||
if (alignedEnd < alignedBegin) {
|
||||
alignedEnd = alignedBegin;
|
||||
// We use flashWrite overload that handles proper alignment
|
||||
if (ESP.flashWrite(addr, src, size)) {
|
||||
return FLASH_HAL_OK;
|
||||
} 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) {
|
||||
|
@ -127,6 +127,7 @@ void _exit(int status) {
|
||||
abort();
|
||||
}
|
||||
|
||||
int atexit(void (*func)()) __attribute__((weak));
|
||||
int atexit(void (*func)()) {
|
||||
(void) func;
|
||||
return 0;
|
||||
|
@ -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)
|
||||
{
|
||||
sntp_stop();
|
||||
|
||||
// There is no way to tell when DST starts or stop with this API
|
||||
// So DST is always integrated in TZ
|
||||
// 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(1, server2);
|
||||
setServer(2, server3);
|
||||
|
||||
sntp_init();
|
||||
}
|
||||
|
||||
void setTZ(const char* tz){
|
||||
|
@ -17,9 +17,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <pgmspace.h>
|
||||
#include <esp8266_undocumented.h>
|
||||
#include "../debug.h"
|
||||
#include "../esp8266_undocumented.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -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>`__
|
||||
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -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
|
||||
* 1 : ``WL_NO_SSID_AVAIL``\ in case configured SSID cannot be reached
|
||||
* 3 : ``WL_CONNECTED`` after successful connection is established
|
||||
* 4 : ``WL_CONNECT_FAILED`` if password is incorrect
|
||||
* 6 : ``WL_DISCONNECTED`` if module is not configured in station mode
|
||||
* 4 : ``WL_CONNECT_FAILED`` if connection failed
|
||||
* 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.
|
||||
|
||||
|
@ -251,7 +251,8 @@ Function returns one of the following connection statuses:
|
||||
|
||||
- ``WL_CONNECTED`` after successful connection is established
|
||||
- ``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_DISCONNECTED`` if module is not configured in station mode
|
||||
- ``-1`` on timeout
|
||||
|
@ -571,15 +571,16 @@ Example header data:
|
||||
|
||||
::
|
||||
|
||||
[HTTP_USER_AGENT] => ESP8266-http-Update
|
||||
[HTTP_X_ESP8266_STA_MAC] => 18:FE:AA:AA:AA:AA
|
||||
[HTTP_X_ESP8266_AP_MAC] => 1A:FE:AA:AA:AA:AA
|
||||
[HTTP_X_ESP8266_FREE_SPACE] => 671744
|
||||
[HTTP_X_ESP8266_SKETCH_SIZE] => 373940
|
||||
[HTTP_X_ESP8266_SKETCH_MD5] => a56f8ef78a0bebd812f62067daf1408a
|
||||
[HTTP_X_ESP8266_CHIP_SIZE] => 4194304
|
||||
[HTTP_X_ESP8266_SDK_VERSION] => 1.3.0
|
||||
[HTTP_X_ESP8266_VERSION] => DOOR-7-g14f53a19
|
||||
[User-Agent] => ESP8266-http-Update
|
||||
[x-ESP8266-STA-MAC] => 18:FE:AA:AA:AA:AA
|
||||
[x-ESP8266-AP-MAC] => 1A:FE:AA:AA:AA:AA
|
||||
[x-ESP8266-free-space] => 671744
|
||||
[x-ESP8266-sketch-size] => 373940
|
||||
[x-ESP8266-sketch-md5] => a56f8ef78a0bebd812f62067daf1408a
|
||||
[x-ESP8266-chip-size] => 4194304
|
||||
[x-ESP8266-sdk-version] => 1.3.0
|
||||
[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:
|
||||
|
||||
@ -608,20 +609,20 @@ With this information the script now can check if an update is needed. It is als
|
||||
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);
|
||||
echo "only for ESP8266 updater!\n";
|
||||
exit();
|
||||
}
|
||||
|
||||
if(
|
||||
!check_header('HTTP_X_ESP8266_STA_MAC') ||
|
||||
!check_header('HTTP_X_ESP8266_AP_MAC') ||
|
||||
!check_header('HTTP_X_ESP8266_FREE_SPACE') ||
|
||||
!check_header('HTTP_X_ESP8266_SKETCH_SIZE') ||
|
||||
!check_header('HTTP_X_ESP8266_SKETCH_MD5') ||
|
||||
!check_header('HTTP_X_ESP8266_CHIP_SIZE') ||
|
||||
!check_header('HTTP_X_ESP8266_SDK_VERSION')
|
||||
!check_header('x-ESP8266-STA-MAC') ||
|
||||
!check_header('x-ESP8266-AP-MAC') ||
|
||||
!check_header('x-ESP8266-free-space') ||
|
||||
!check_header('x-ESP8266-sketch-size') ||
|
||||
!check_header('x-ESP8266-sketch-md5') ||
|
||||
!check_header('x-ESP8266-chip-size') ||
|
||||
!check_header('x-ESP8266-sdk-version')
|
||||
) {
|
||||
header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
|
||||
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"
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$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
|
||||
// MD5 hash between local binary and ESP8266 binary do not match if not.
|
||||
// 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'])
|
||||
|| $_SERVER["HTTP_X_ESP8266_SKETCH_MD5"] != md5_file($localBinary)) {
|
||||
if((!check_header('x-ESP8266-sdk-version') && $db[$_SERVER['x-ESP8266-STA-MAC']] != $_SERVER['x-ESP8266-version'])
|
||||
|| $_SERVER["x-ESP8266-sketch-md5"] != md5_file($localBinary)) {
|
||||
sendFile($localBinary);
|
||||
} else {
|
||||
header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304);
|
||||
|
@ -35,17 +35,11 @@ extern "C" uint32_t _EEPROM_start;
|
||||
|
||||
EEPROMClass::EEPROMClass(uint32_t sector)
|
||||
: _sector(sector)
|
||||
, _data(0)
|
||||
, _size(0)
|
||||
, _dirty(false)
|
||||
{
|
||||
}
|
||||
|
||||
EEPROMClass::EEPROMClass(void)
|
||||
: _sector((((uint32_t)&_EEPROM_start - 0x40200000) / SPI_FLASH_SEC_SIZE))
|
||||
, _data(0)
|
||||
, _size(0)
|
||||
, _dirty(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -68,9 +68,9 @@ public:
|
||||
|
||||
protected:
|
||||
uint32_t _sector;
|
||||
uint8_t* _data;
|
||||
size_t _size;
|
||||
bool _dirty;
|
||||
uint8_t* _data = nullptr;
|
||||
size_t _size = 0;
|
||||
bool _dirty = false;
|
||||
};
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_EEPROM)
|
||||
|
@ -47,12 +47,10 @@ extern "C" {
|
||||
#include "include/UdpContext.h"
|
||||
//#define DEBUG_SSDP Serial
|
||||
|
||||
#define SSDP_INTERVAL 1200
|
||||
#define SSDP_PORT 1900
|
||||
#define SSDP_METHOD_SIZE 10
|
||||
#define SSDP_URI_SIZE 2
|
||||
#define SSDP_BUFFER_SIZE 64
|
||||
#define SSDP_MULTICAST_TTL 2
|
||||
|
||||
// ssdp ipv6 is FF05::C
|
||||
// lwip-v2's igmp_joingroup only supports IPv4
|
||||
@ -125,19 +123,8 @@ struct SSDPTimer {
|
||||
ETSTimer timer;
|
||||
};
|
||||
|
||||
SSDPClass::SSDPClass() :
|
||||
_server(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)
|
||||
SSDPClass::SSDPClass()
|
||||
: _respondToAddr(0,0,0,0)
|
||||
{
|
||||
_uuid[0] = '\0';
|
||||
_modelNumber[0] = '\0';
|
||||
|
@ -46,6 +46,9 @@ class UdpContext;
|
||||
#define SSDP_MODEL_VERSION_SIZE 32
|
||||
#define SSDP_MANUFACTURER_SIZE 64
|
||||
#define SSDP_MANUFACTURER_URL_SIZE 128
|
||||
#define SSDP_INTERVAL_SECONDS 1200
|
||||
#define SSDP_MULTICAST_TTL 2
|
||||
#define SSDP_HTTP_PORT 80
|
||||
|
||||
typedef enum {
|
||||
NONE,
|
||||
@ -101,20 +104,20 @@ class SSDPClass{
|
||||
void _stopTimer();
|
||||
static void _onTimerStatic(SSDPClass* self);
|
||||
|
||||
UdpContext* _server;
|
||||
SSDPTimer* _timer;
|
||||
uint16_t _port;
|
||||
uint8_t _ttl;
|
||||
uint32_t _interval;
|
||||
UdpContext* _server = nullptr;
|
||||
SSDPTimer* _timer = nullptr;
|
||||
uint16_t _port = SSDP_HTTP_PORT;
|
||||
uint8_t _ttl = SSDP_MULTICAST_TTL;
|
||||
uint32_t _interval = SSDP_INTERVAL_SECONDS;
|
||||
|
||||
IPAddress _respondToAddr;
|
||||
uint16_t _respondToPort;
|
||||
uint16_t _respondToPort = 0;
|
||||
|
||||
bool _pending;
|
||||
bool _st_is_uuid;
|
||||
unsigned short _delay;
|
||||
unsigned long _process_time;
|
||||
unsigned long _notify_time;
|
||||
bool _pending = false;
|
||||
bool _st_is_uuid = false;
|
||||
unsigned short _delay = 0;
|
||||
unsigned long _process_time = 0;
|
||||
unsigned long _notify_time = 0;
|
||||
|
||||
char _schemaURL[SSDP_SCHEMA_URL_SIZE];
|
||||
char _uuid[SSDP_UUID_SIZE];
|
||||
|
@ -39,47 +39,12 @@ namespace esp8266webserver {
|
||||
template <typename ServerType>
|
||||
ESP8266WebServerTemplate<ServerType>::ESP8266WebServerTemplate(IPAddress addr, int 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>
|
||||
ESP8266WebServerTemplate<ServerType>::ESP8266WebServerTemplate(int 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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -263,35 +263,35 @@ protected:
|
||||
|
||||
ServerType _server;
|
||||
ClientType _currentClient;
|
||||
HTTPMethod _currentMethod;
|
||||
HTTPMethod _currentMethod = HTTP_ANY;
|
||||
String _currentUri;
|
||||
uint8_t _currentVersion;
|
||||
HTTPClientStatus _currentStatus;
|
||||
unsigned long _statusChange;
|
||||
bool _keepAlive;
|
||||
uint8_t _currentVersion = 0;
|
||||
HTTPClientStatus _currentStatus = HC_NONE;
|
||||
unsigned long _statusChange = 0;
|
||||
|
||||
RequestHandlerType* _currentHandler;
|
||||
RequestHandlerType* _firstHandler;
|
||||
RequestHandlerType* _lastHandler;
|
||||
RequestHandlerType* _currentHandler = nullptr;
|
||||
RequestHandlerType* _firstHandler = nullptr;
|
||||
RequestHandlerType* _lastHandler = nullptr;
|
||||
THandlerFunction _notFoundHandler;
|
||||
THandlerFunction _fileUploadHandler;
|
||||
|
||||
int _currentArgCount;
|
||||
RequestArgument* _currentArgs;
|
||||
int _currentArgsHavePlain;
|
||||
int _currentArgCount = 0;
|
||||
RequestArgument* _currentArgs = nullptr;
|
||||
int _currentArgsHavePlain = 0;
|
||||
std::unique_ptr<HTTPUpload> _currentUpload;
|
||||
int _postArgsLen;
|
||||
RequestArgument* _postArgs;
|
||||
int _postArgsLen = 0;
|
||||
RequestArgument* _postArgs = nullptr;
|
||||
|
||||
int _headerKeysCount;
|
||||
RequestArgument* _currentHeaders;
|
||||
int _headerKeysCount = 0;
|
||||
RequestArgument* _currentHeaders = nullptr;
|
||||
|
||||
size_t _contentLength;
|
||||
size_t _contentLength = 0;
|
||||
String _responseHeaders;
|
||||
|
||||
String _hostHeader;
|
||||
bool _chunked;
|
||||
bool _corsEnabled;
|
||||
bool _chunked = false;
|
||||
bool _corsEnabled = false;
|
||||
bool _keepAlive = false;
|
||||
|
||||
String _snonce; // Store noance and opaque for future comparison
|
||||
String _sopaque;
|
||||
|
@ -21,7 +21,7 @@
|
||||
#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__)
|
||||
#else
|
||||
#define DEBUG_BSSL(...)
|
||||
|
@ -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)
|
||||
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,
|
||||
state->state.channel,
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
if (beginResult == WL_WRONG_PASSWORD)
|
||||
{
|
||||
DEBUG_WIFI("core: resume: WiFi.begin wrong password\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->state.mode & WIFI_AP)
|
||||
|
@ -60,6 +60,9 @@ static void printWiFiStatus(wl_status_t status)
|
||||
case WL_CONNECT_FAILED:
|
||||
DEBUG_WIFI_MULTI("[WIFIM] Connecting failed.\n");
|
||||
break;
|
||||
case WL_WRONG_PASSWORD:
|
||||
DEBUG_WIFI_MULTI("[WIFIM] Wrong password.\n");
|
||||
break;
|
||||
default:
|
||||
DEBUG_WIFI_MULTI("[WIFIM] Connecting failed (%d).\n", status);
|
||||
break;
|
||||
|
@ -624,8 +624,9 @@ wl_status_t ESP8266WiFiSTAClass::status() {
|
||||
case STATION_NO_AP_FOUND:
|
||||
return WL_NO_SSID_AVAIL;
|
||||
case STATION_CONNECT_FAIL:
|
||||
case STATION_WRONG_PASSWORD:
|
||||
return WL_CONNECT_FAILED;
|
||||
case STATION_WRONG_PASSWORD:
|
||||
return WL_WRONG_PASSWORD;
|
||||
case STATION_IDLE:
|
||||
return WL_IDLE_STATUS;
|
||||
default:
|
||||
|
@ -59,7 +59,7 @@ extern "C" {
|
||||
|
||||
#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__)
|
||||
#else
|
||||
#define DEBUG_BSSL(...)
|
||||
@ -664,7 +664,7 @@ extern "C" {
|
||||
if (!xc->done_cert) {
|
||||
br_sha1_update(&xc->sha1_cert, 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: ");
|
||||
for (size_t i=0; i<len; i++) {
|
||||
DEBUG_ESP_PORT.printf_P(PSTR("%02x "), buf[i] & 0xff);
|
||||
|
@ -44,18 +44,12 @@ extern "C" {
|
||||
WiFiServer::WiFiServer(const IPAddress& addr, uint16_t port)
|
||||
: _port(port)
|
||||
, _addr(addr)
|
||||
, _listen_pcb(nullptr)
|
||||
, _unclaimed(nullptr)
|
||||
, _discarded(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
WiFiServer::WiFiServer(uint16_t port)
|
||||
: _port(port)
|
||||
, _addr(IP_ANY_TYPE)
|
||||
, _listen_pcb(nullptr)
|
||||
, _unclaimed(nullptr)
|
||||
, _discarded(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -70,10 +70,10 @@ class WiFiServer : public Server {
|
||||
protected:
|
||||
uint16_t _port;
|
||||
IPAddress _addr;
|
||||
tcp_pcb* _listen_pcb;
|
||||
tcp_pcb* _listen_pcb = nullptr;
|
||||
|
||||
ClientContext* _unclaimed;
|
||||
ClientContext* _discarded;
|
||||
ClientContext* _unclaimed = nullptr;
|
||||
ClientContext* _discarded = nullptr;
|
||||
enum { _ndDefault, _ndFalse, _ndTrue } _noDelay = _ndDefault;
|
||||
|
||||
public:
|
||||
|
@ -55,7 +55,8 @@ typedef enum {
|
||||
WL_CONNECTED = 3,
|
||||
WL_CONNECT_FAILED = 4,
|
||||
WL_CONNECTION_LOST = 5,
|
||||
WL_DISCONNECTED = 6
|
||||
WL_WRONG_PASSWORD = 6,
|
||||
WL_DISCONNECTED = 7
|
||||
} wl_status_t;
|
||||
|
||||
/* Encryption modes */
|
||||
|
@ -27,7 +27,8 @@
|
||||
|
||||
#include "ESP8266mDNS.h"
|
||||
#include "LEAmDNS_Priv.h"
|
||||
|
||||
#include <LwipIntf.h> // LwipIntf::stateUpCB()
|
||||
#include "lwip/igmp.h"
|
||||
|
||||
namespace esp8266
|
||||
{
|
||||
@ -61,13 +62,7 @@ MDNSResponder::MDNSResponder(void)
|
||||
m_pUDPContext(0),
|
||||
m_pcHostname(0),
|
||||
m_pServiceQueries(0),
|
||||
m_fnServiceTxtCallback(0),
|
||||
#ifdef ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE
|
||||
m_bPassivModeEnabled(true),
|
||||
#else
|
||||
m_bPassivModeEnabled(false),
|
||||
#endif
|
||||
m_netif(nullptr)
|
||||
m_fnServiceTxtCallback(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -93,104 +88,29 @@ MDNSResponder::~MDNSResponder(void)
|
||||
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;
|
||||
|
||||
if (0 == m_pUDPContext)
|
||||
if (_setHostname(p_pcHostname))
|
||||
{
|
||||
if (_setHostname(p_pcHostname))
|
||||
{
|
||||
|
||||
//// 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 ? : "-"));
|
||||
});
|
||||
bResult = _restart();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -207,9 +127,6 @@ bool MDNSResponder::close(void)
|
||||
|
||||
if (0 != m_pUDPContext)
|
||||
{
|
||||
m_GotIPHandler.reset(); // reset WiFi event callbacks.
|
||||
m_DisconnectedHandler.reset();
|
||||
|
||||
_announce(false, true);
|
||||
_resetProbeStatus(false); // Stop probing
|
||||
_releaseServiceQueries();
|
||||
@ -1329,11 +1246,6 @@ bool MDNSResponder::notifyAPChange(void)
|
||||
*/
|
||||
bool MDNSResponder::update(void)
|
||||
{
|
||||
|
||||
if (m_bPassivModeEnabled)
|
||||
{
|
||||
m_bPassivModeEnabled = false;
|
||||
}
|
||||
return _process(true);
|
||||
}
|
||||
|
||||
@ -1374,6 +1286,94 @@ MDNSResponder::hMDNSService MDNSResponder::enableArduino(uint16_t p_u16Port,
|
||||
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
|
||||
|
||||
|
@ -164,6 +164,10 @@ namespace MDNSImplementation
|
||||
*/
|
||||
#define MDNS_QUERYSERVICES_WAIT_TIME 1000
|
||||
|
||||
/*
|
||||
Timeout for udpContext->sendtimeout()
|
||||
*/
|
||||
#define MDNS_UDPCONTEXT_TIMEOUT 50
|
||||
|
||||
/**
|
||||
MDNSResponder
|
||||
@ -185,6 +189,8 @@ public:
|
||||
{
|
||||
return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL);
|
||||
}
|
||||
bool _joinMulticastGroups(void);
|
||||
bool _leaveMulticastGroups(void);
|
||||
|
||||
// Finish MDNS processing
|
||||
bool close(void);
|
||||
@ -1184,6 +1190,7 @@ protected:
|
||||
~stcMDNSSendParameter(void);
|
||||
|
||||
bool clear(void);
|
||||
bool clearCachedNames(void);
|
||||
|
||||
bool shiftOffset(uint16_t p_u16Shift);
|
||||
|
||||
@ -1199,12 +1206,8 @@ protected:
|
||||
UdpContext* m_pUDPContext;
|
||||
char* m_pcHostname;
|
||||
stcMDNSServiceQuery* m_pServiceQueries;
|
||||
WiFiEventHandler m_DisconnectedHandler;
|
||||
WiFiEventHandler m_GotIPHandler;
|
||||
MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback;
|
||||
bool m_bPassivModeEnabled;
|
||||
stcProbeInformation m_HostProbeInformation;
|
||||
const netif* m_netif; // network interface to run on
|
||||
|
||||
/** CONTROL **/
|
||||
/* MAINTENANCE */
|
||||
@ -1259,11 +1262,6 @@ protected:
|
||||
uint16_t p_u16QueryType,
|
||||
stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0);
|
||||
|
||||
const IPAddress _getResponseMulticastInterface() const
|
||||
{
|
||||
return IPAddress(m_netif->ip_addr);
|
||||
}
|
||||
|
||||
uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader,
|
||||
bool* p_pbFullNameMatch = 0) const;
|
||||
uint8_t _replyMaskForService(const stcMDNS_RRHeader& p_RRHeader,
|
||||
|
@ -33,7 +33,7 @@
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
#include <lwip/igmp.h>
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
#include <lwip/mld6.h>
|
||||
#endif
|
||||
|
||||
@ -172,7 +172,7 @@ const char* clsLEAMDNSHost::clsConsts::pcUDP = "udp";
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
const char* clsLEAMDNSHost::clsConsts::pcReverseIPv4Domain = "in-addr";
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
const char* clsLEAMDNSHost::clsConsts::pcReverseIPv6Domain = "ip6";
|
||||
#endif
|
||||
const char* clsLEAMDNSHost::clsConsts::pcReverseTopDomain = "arpa";
|
||||
@ -904,7 +904,7 @@ bool clsLEAMDNSHost::_joinMulticastGroups(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_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))));
|
||||
@ -937,7 +937,7 @@ bool clsLEAMDNSHost::_leaveMulticastGroups()
|
||||
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("\n")););
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_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)*/))
|
||||
{
|
||||
|
@ -110,7 +110,7 @@
|
||||
|
||||
#define MDNS_IPV4_SUPPORT
|
||||
#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
|
||||
|
||||
namespace esp8266
|
||||
@ -136,7 +136,7 @@ protected:
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
static constexpr uint16_t u16IPv4Size = 4; // IPv4 address size in bytes
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
static constexpr uint16_t u16IPv6Size = 16; // IPv6 address size in bytes
|
||||
#endif
|
||||
static constexpr size_t stServiceTxtMaxLength = 1300; // Maximum length for all service txts for one service
|
||||
@ -168,7 +168,7 @@ protected:
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
static const char* pcReverseIPv4Domain; // "in-addr";
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
static const char* pcReverseIPv6Domain; // "ip6";
|
||||
#endif
|
||||
static const char* pcReverseTopDomain; // "arpa";
|
||||
@ -246,7 +246,7 @@ protected:
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
V4 = 0x01,
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
V6 = 0x02,
|
||||
#endif
|
||||
};
|
||||
@ -784,7 +784,7 @@ protected:
|
||||
bool clear(void);
|
||||
};
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
/**
|
||||
clsRRAnswerAAAA
|
||||
*/
|
||||
@ -935,7 +935,7 @@ public:
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
IPv4Address = 0x10, // IPv4 address
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
IPv6Address = 0x20, // IPv6 address
|
||||
#endif
|
||||
};
|
||||
@ -1004,7 +1004,7 @@ public:
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
clsIPAddressWithTTL::list m_IPv4Addresses; // 3. level answer (A, using host domain), eg. 123.456.789.012
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
clsIPAddressWithTTL::list m_IPv6Addresses; // 3. level answer (AAAA, using host domain), eg. 1234::09
|
||||
#endif
|
||||
typeQueryAnswerType m_QueryAnswerFlags; // enuQueryAnswerType
|
||||
@ -1029,7 +1029,7 @@ public:
|
||||
const clsIPAddressWithTTL* IPv4AddressAtIndex(uint32_t p_u32Index) const;
|
||||
clsIPAddressWithTTL* IPv4AddressAtIndex(uint32_t p_u32Index);
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
bool releaseIPv6Addresses(void);
|
||||
bool addIPv6Address(clsIPAddressWithTTL* p_pIPAddress);
|
||||
bool removeIPv6Address(clsIPAddressWithTTL* p_pIPAddress);
|
||||
@ -1081,7 +1081,7 @@ public:
|
||||
bool IPv4AddressAvailable(void) const;
|
||||
clsIPAddressVector IPv4Addresses(void) const;
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
bool IPv6AddressAvailable(void) const;
|
||||
clsIPAddressVector IPv6Addresses(void) const;
|
||||
#endif
|
||||
@ -1362,7 +1362,7 @@ protected:
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
bool _processAAnswer(const clsRRAnswerA* p_pAAnswer);
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
bool _processAAAAAnswer(const clsRRAnswerAAAA* p_pAAAAAnswer);
|
||||
#endif
|
||||
|
||||
@ -1426,7 +1426,7 @@ protected:
|
||||
uint16_t p_u16RDLength);
|
||||
bool _readRRAnswerTXT(clsRRAnswerTXT& p_rRRAnswerTXT,
|
||||
uint16_t p_u16RDLength);
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
bool _readRRAnswerAAAA(clsRRAnswerAAAA& p_rRRAnswerAAAA,
|
||||
uint16_t p_u16RDLength);
|
||||
#endif
|
||||
@ -1455,7 +1455,7 @@ protected:
|
||||
bool _buildDomainForReverseIPv4(IPAddress p_IPv4Address,
|
||||
clsRRDomain& p_rReverseIPv4Domain) const;
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
bool _buildDomainForReverseIPv6(IPAddress p_IPv4Address,
|
||||
clsRRDomain& p_rReverseIPv6Domain) const;
|
||||
#endif
|
||||
@ -1520,7 +1520,7 @@ protected:
|
||||
clsSendParameter& p_rSendParameter);
|
||||
bool _writeMDNSAnswer_TXT(clsService& p_rService,
|
||||
clsSendParameter& p_rSendParameter);
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
bool _writeMDNSAnswer_AAAA(IPAddress p_IPAddress,
|
||||
clsSendParameter& p_rSendParameter);
|
||||
bool _writeMDNSAnswer_PTR_IPv6(IPAddress p_IPAddress,
|
||||
@ -1537,7 +1537,7 @@ protected:
|
||||
bool _writeMDNSAnswer_NSEC_PTR_IPv4(IPAddress p_IPAddress,
|
||||
clsSendParameter& p_rSendParameter);
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
bool _writeMDNSAnswer_NSEC_PTR_IPv6(IPAddress p_IPAddress,
|
||||
clsSendParameter& p_rSendParameter);
|
||||
#endif
|
||||
|
@ -218,7 +218,7 @@ bool clsLEAMDNSHost::_parseQuery(netif* pNetIf,
|
||||
(true)
|
||||
#endif
|
||||
&&
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
(m_pUDPContext->getRemoteAddress().isV6()) &&
|
||||
(ip6_addr_islinklocal(ip_2_ip6((const ip_addr_t*)m_pUDPContext->getRemoteAddress())))
|
||||
#else
|
||||
@ -304,7 +304,7 @@ bool clsLEAMDNSHost::_parseQuery(netif* pNetIf,
|
||||
sendParameter.m_u32HostReplyMask &= ~static_cast<uint32_t>(enuContentFlag::PTR_IPv4);
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if (u32HostMatchMask & static_cast<uint32_t>(enuContentFlag::PTR_IPv6))
|
||||
{
|
||||
// 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))
|
||||
{
|
||||
// IPv6 address was asked for
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if ((enuAnswerType::AAAA == pKnownRRAnswer->answerType()) &&
|
||||
(((stcRRAnswerAAAA*)pKnownRRAnswer)->m_IPAddress == _getResponderIPAddress(pNetIf, enuIPProtocolType::V6)))
|
||||
{
|
||||
@ -381,7 +381,7 @@ bool clsLEAMDNSHost::_parseQuery(netif* pNetIf,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if (enuAnswerType::AAAA == pKnownRRAnswer->answerType())
|
||||
{
|
||||
IPAddress localIPAddress(_getResponderIPAddress(pNetIf, enuIPProtocolType::V6));
|
||||
@ -775,7 +775,7 @@ bool clsLEAMDNSHost::_processAnswers(netif* pNetIf, const clsLEAMDNSHost::clsRRA
|
||||
bResult = _processAAnswer((clsRRAnswerA*)pRRAnswer);
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
// AAAA -> IPv6Address
|
||||
else if (enuAnswerType::AAAA == pRRAnswer->answerType())
|
||||
{
|
||||
@ -802,7 +802,7 @@ bool clsLEAMDNSHost::_processAnswers(netif* pNetIf, const clsLEAMDNSHost::clsRRA
|
||||
bPossibleEcho = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if ((enuAnswerType::AAAA == pRRAnswer->answerType()) &&
|
||||
(((clsRRAnswerAAAA*)pRRAnswer)->m_IPAddress == _getResponderIPAddress(pNetIf, enuIPProtocolType::V6)))
|
||||
{
|
||||
@ -1159,7 +1159,7 @@ bool clsLEAMDNSHost::_processAAnswer(const clsLEAMDNSHost::clsRRAnswerA* p_pAAns
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
/*
|
||||
clsLEAmDNS2_Host::_processAAAAAnswer (level 3)
|
||||
*/
|
||||
@ -1298,7 +1298,7 @@ bool clsLEAMDNSHost::_updateProbeStatus()
|
||||
true
|
||||
#endif
|
||||
) || (
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
_getResponderIPAddress(pNetIf, enuIPProtocolType::V6).isSet() // OR has IPv6 address
|
||||
#else
|
||||
true
|
||||
@ -1511,7 +1511,7 @@ bool clsLEAMDNSHost::_sendHostProbe()
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::A); // Add A answer
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
sendParameter.m_u32HostReplyMask |= static_cast<uint32_t>(enuContentFlag::AAAA); // Add AAAA answer
|
||||
#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::PTR_IPv4); // PTR_IPv4 answer
|
||||
#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::PTR_IPv6); // PTR_IPv6 answer
|
||||
#endif
|
||||
@ -1892,7 +1892,7 @@ bool clsLEAMDNSHost::_checkQueryCache()
|
||||
pQAnswer->releaseIPv4Addresses();
|
||||
queryAnswerContentFlags |= static_cast<clsQuery::clsAnswer::typeQueryAnswerType>(clsQuery::clsAnswer::enuQueryAnswerType::IPv4Address);
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
pQAnswer->releaseIPv6Addresses();
|
||||
queryAnswerContentFlags |= static_cast<clsQuery::clsAnswer::typeQueryAnswerType>(clsQuery::clsAnswer::enuQueryAnswerType::IPv6Address);
|
||||
#endif
|
||||
@ -1991,7 +1991,7 @@ bool clsLEAMDNSHost::_checkQueryCache()
|
||||
pQAnswer->removeIPv4Address(pIPv4Address);
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
// IPv6Address (from AAAA)
|
||||
clsQuery::clsAnswer::clsIPAddressWithTTL::list expiredIPv6Addresses;
|
||||
bool bAAAAUpdateQuerySent = false;
|
||||
@ -2095,7 +2095,7 @@ uint32_t clsLEAMDNSHost::_replyMaskForHost(netif* pNetIf,
|
||||
u32ReplyMask |= static_cast<uint32_t>(enuContentFlag::PTR_IPv4);
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
clsRRDomain reverseIPv6Domain;
|
||||
if ((_getResponderIPAddress(pNetIf, enuIPProtocolType::V6).isSet()) &&
|
||||
(_buildDomainForReverseIPv6(_getResponderIPAddress(pNetIf, enuIPProtocolType::V6), reverseIPv6Domain)) &&
|
||||
@ -2121,7 +2121,7 @@ uint32_t clsLEAMDNSHost::_replyMaskForHost(netif* pNetIf,
|
||||
u32ReplyMask |= static_cast<uint32_t>(enuContentFlag::A);
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if ((DNS_RRTYPE_AAAA == p_RRHeader.m_Attributes.m_u16Type) ||
|
||||
(DNS_RRTYPE_ANY == p_RRHeader.m_Attributes.m_u16Type))
|
||||
{
|
||||
|
@ -141,7 +141,7 @@ bool clsLEAMDNSHost::_printRRAnswer(const clsLEAMDNSHost::clsRRAnswer& p_RRAnswe
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
case DNS_RRTYPE_AAAA:
|
||||
DEBUG_OUTPUT.printf_P(PSTR("AAAA IP:%s"), ((clsRRAnswerAAAA*&)p_RRAnswer)->m_IPAddress.toString().c_str());
|
||||
break;
|
||||
@ -175,7 +175,7 @@ const char* clsLEAMDNSHost::_RRType2Name(uint16_t p_u16RRType) const
|
||||
#endif
|
||||
case DNS_RRTYPE_PTR: strcpy_P(acRRName, PSTR("PTR")); 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;
|
||||
#endif
|
||||
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
|
||||
}
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if (p_pNSECBitmap->getBit(DNS_RRTYPE_AAAA))
|
||||
{
|
||||
strcat_P(acFlagsString, PSTR("AAAA ")); // 5
|
||||
|
@ -1898,7 +1898,7 @@ bool clsLEAMDNSHost::clsRRAnswerTXT::clear(void)
|
||||
|
||||
*/
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
/*
|
||||
clsLEAMDNSHost::clsRRAnswerAAAA::clsRRAnswerAAAA constructor
|
||||
|
||||
@ -2398,7 +2398,7 @@ bool clsLEAMDNSHost::clsQuery::clsAnswer::clear(void)
|
||||
(true)
|
||||
#endif
|
||||
&&
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
(releaseIPv6Addresses())
|
||||
#else
|
||||
(true)
|
||||
@ -2528,7 +2528,7 @@ const clsLEAMDNSHost::clsQuery::clsAnswer::clsIPAddressWithTTL* clsLEAMDNSHost::
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
/*
|
||||
clsLEAMDNSHost::clsQuery::clsAnswer::releaseIPv6Addresses
|
||||
|
||||
@ -2793,7 +2793,7 @@ clsLEAMDNSHost::clsQuery::clsAnswerAccessor::clsIPAddressVector clsLEAMDNSHost::
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
/*
|
||||
clsLEAMDNSHost::clsQuery::clsAnswerAccessor::IPv6AddressAvailable
|
||||
|
||||
@ -2913,7 +2913,7 @@ size_t clsLEAMDNSHost::clsQuery::clsAnswerAccessor::printTo(Print& p_Print) cons
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if (IPv6AddressAvailable())
|
||||
{
|
||||
stLen += p_Print.print(cpcI);
|
||||
|
@ -84,7 +84,7 @@ bool clsLEAMDNSHost::_sendMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParamete
|
||||
DEBUG_OUTPUT.printf_P(PSTR("%s _sendMessage: No IPv4 address available!\n"), _DH());
|
||||
});
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
// Only send out IPv6 messages, if we've got an IPv6 address
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if (((!ipRemote.isSet()) || // NO remote IP
|
||||
(ipRemote.isV6())) && // OR IPv6
|
||||
(u8AvailableProtocols & static_cast<uint8_t>(enuIPProtocolType::V6))) // AND IPv6 protocol available
|
||||
@ -182,7 +182,7 @@ bool clsLEAMDNSHost::_sendMessage_Multicast(netif* pNetIf, clsLEAMDNSHost::clsSe
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if (p_IPProtocolTypes & static_cast<uint8_t>(enuIPProtocolType::V6))
|
||||
{
|
||||
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()););
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
// AAAA
|
||||
if ((bResult) &&
|
||||
(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
|
||||
bool bNeedsAdditionalAnswerA = false;
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
bool bNeedsAdditionalAnswerAAAA = false;
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if ((bResult) &&
|
||||
(!(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()););
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
// Answer AAAA needed?
|
||||
if ((bResult) &&
|
||||
(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));
|
||||
u32NSECContent &= ~static_cast<uint32_t>(enuContentFlag::PTR_IPv4);
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
uint32_t u32NSECContent_PTR_IPv6 = (u32NSECContent & static_cast<uint32_t>(enuContentFlag::PTR_IPv6));
|
||||
u32NSECContent &= ~static_cast<uint32_t>(enuContentFlag::PTR_IPv6);
|
||||
#endif
|
||||
@ -491,7 +491,7 @@ bool clsLEAMDNSHost::_prepareMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParam
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
+ (u32NSECContent_PTR_IPv4 ? 1 : 0)
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
+ (u32NSECContent_PTR_IPv6 ? 1 : 0)
|
||||
#endif
|
||||
))
|
||||
@ -504,7 +504,7 @@ bool clsLEAMDNSHost::_prepareMessage(netif* pNetIf, clsLEAMDNSHost::clsSendParam
|
||||
((!_getResponderIPAddress(pNetIf, (enuIPProtocolType::V4)).isSet()) ||
|
||||
(_writeMDNSAnswer_NSEC_PTR_IPv4(_getResponderIPAddress(pNetIf, (enuIPProtocolType::V4)), p_rSendParameter))))
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
// Write separate answer for host PTR IPv6
|
||||
&& ((!u32NSECContent_PTR_IPv6) ||
|
||||
((!_getResponderIPAddress(pNetIf, (enuIPProtocolType::V6)).isSet()) ||
|
||||
@ -566,7 +566,7 @@ bool clsLEAMDNSHost::_sendQuery(const clsLEAMDNSHost::clsQuery& p_Query,
|
||||
#ifdef MDNS_IPV4_SUPPORT
|
||||
bResult = _addQueryRecord(sendParameter, p_Query.m_Domain, DNS_RRTYPE_A);
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
bResult = _addQueryRecord(sendParameter, p_Query.m_Domain, DNS_RRTYPE_AAAA);
|
||||
#endif
|
||||
break;
|
||||
@ -623,7 +623,7 @@ IPAddress clsLEAMDNSHost::_getResponderIPAddress(netif* pNetIf, enuIPProtocolTyp
|
||||
ipResponder = netif_ip_addr4(pNetIf);
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if (enuIPProtocolType::V6 == p_IPProtocolType)
|
||||
{
|
||||
bool bCheckLinkLocal = true;
|
||||
@ -731,7 +731,7 @@ bool clsLEAMDNSHost::_readRRAnswer(clsLEAMDNSHost::clsRRAnswer*& p_rpRRAnswer)
|
||||
p_rpRRAnswer = new clsRRAnswerTXT(header, u32TTL);
|
||||
bResult = _readRRAnswerTXT(*(clsRRAnswerTXT*&)p_rpRRAnswer, u16RDLength);
|
||||
break;
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
case DNS_RRTYPE_AAAA:
|
||||
p_rpRRAnswer = new clsRRAnswerAAAA(header, u32TTL);
|
||||
bResult = _readRRAnswerAAAA(*(clsRRAnswerAAAA*&)p_rpRRAnswer, u16RDLength);
|
||||
@ -779,7 +779,7 @@ bool clsLEAMDNSHost::_readRRAnswer(clsLEAMDNSHost::clsRRAnswer*& p_rpRRAnswer)
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
case DNS_RRTYPE_AAAA:
|
||||
DEBUG_OUTPUT.printf_P(PSTR("AAAA IP:%s"), ((clsRRAnswerAAAA*&)p_rpRRAnswer)->m_IPAddress.toString().c_str());
|
||||
break;
|
||||
@ -968,7 +968,7 @@ bool clsLEAMDNSHost::_readRRAnswerTXT(clsLEAMDNSHost::clsRRAnswerTXT& p_rRRAnswe
|
||||
return bResult;
|
||||
}
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
bool clsLEAMDNSHost::_readRRAnswerAAAA(clsLEAMDNSHost::clsRRAnswerAAAA& p_rRRAnswerAAAA,
|
||||
uint16_t p_u16RDLength)
|
||||
{
|
||||
@ -1280,7 +1280,7 @@ bool clsLEAMDNSHost::_buildDomainForReverseIPv4(IPAddress p_IPv4Address,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
/*
|
||||
MDNSResponder::_buildDomainForReverseIPv6
|
||||
|
||||
@ -2014,7 +2014,7 @@ bool clsLEAMDNSHost::_writeMDNSAnswer_TXT(clsLEAMDNSHost::clsService& p_rService
|
||||
return bResult;
|
||||
}
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
/*
|
||||
MDNSResponder::_writeMDNSAnswer_AAAA
|
||||
|
||||
@ -2189,7 +2189,7 @@ clsLEAMDNSHost::clsNSECBitmap* clsLEAMDNSHost::_createNSECBitmap(uint32_t p_u32N
|
||||
{
|
||||
pNSECBitmap->setBit(DNS_RRTYPE_PTR); // 12/0x0C
|
||||
}
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
if (p_u32NSECContent & static_cast<uint32_t>(enuContentFlag::AAAA))
|
||||
{
|
||||
pNSECBitmap->setBit(DNS_RRTYPE_AAAA); // 28/0x1C
|
||||
@ -2335,7 +2335,7 @@ bool clsLEAMDNSHost::_writeMDNSAnswer_NSEC_PTR_IPv4(IPAddress p_IPAddress,
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MDNS_IPV6_SUPPORT
|
||||
#ifdef MDNS2_IPV6_SUPPORT
|
||||
/*
|
||||
MDNSResponder::_writeMDNSAnswer_NSEC_PTR_IPv6(host)
|
||||
|
||||
|
@ -85,10 +85,8 @@ bool MDNSResponder::_process(bool p_bUserContext)
|
||||
}
|
||||
else
|
||||
{
|
||||
bResult = (m_netif != nullptr) &&
|
||||
(m_netif->flags & NETIF_FLAG_UP) && // network interface is up and running
|
||||
_updateProbeStatus() && // Probing
|
||||
_checkServiceQueryCache(); // Service query cache check
|
||||
bResult = _updateProbeStatus() && // Probing
|
||||
_checkServiceQueryCache(); // Service query cache check
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
@ -99,13 +97,10 @@ bool MDNSResponder::_process(bool p_bUserContext)
|
||||
bool MDNSResponder::_restart(void)
|
||||
{
|
||||
|
||||
return ((m_netif != nullptr) &&
|
||||
(m_netif->flags & NETIF_FLAG_UP) && // network interface is up and running
|
||||
(_resetProbeStatus(true)) && // Stop and restart probing
|
||||
return ((_resetProbeStatus(true)) && // Stop and restart probing
|
||||
(_allocUDPContext())); // Restart UDP
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
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
|
||||
u8HostOrServiceReplies =
|
||||
sendParameter.m_u8HostReplyMask |= (((m_bPassivModeEnabled) ||
|
||||
(ProbingStatus_Done == m_HostProbeInformation.m_ProbingStatus))
|
||||
sendParameter.m_u8HostReplyMask |= (((ProbingStatus_Done == m_HostProbeInformation.m_ProbingStatus))
|
||||
? _replyMaskForHost(questionRR.m_Header, 0)
|
||||
: 0);
|
||||
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)
|
||||
{
|
||||
// Define service replies, BUT only answer queries after probing is done
|
||||
uint8_t u8ReplyMaskForQuestion = (((m_bPassivModeEnabled) ||
|
||||
(ProbingStatus_Done == pService->m_ProbeInformation.m_ProbingStatus))
|
||||
uint8_t u8ReplyMaskForQuestion = (((ProbingStatus_Done == pService->m_ProbeInformation.m_ProbingStatus))
|
||||
? _replyMaskForService(questionRR.m_Header, *pService, 0)
|
||||
: 0);
|
||||
u8HostOrServiceReplies |= (pService->m_u8ReplyMask |= u8ReplyMaskForQuestion);
|
||||
@ -364,9 +357,8 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea
|
||||
// IP4 address was asked for
|
||||
#ifdef MDNS_IP4_SUPPORT
|
||||
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")););
|
||||
sendParameter.m_u8HostReplyMask &= ~ContentFlag_A;
|
||||
} // else: RData NOT IP4 length !!
|
||||
@ -399,7 +391,8 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea
|
||||
#ifdef MDNS_IP4_SUPPORT
|
||||
if (AnswerType_A == pKnownRRAnswer->answerType())
|
||||
{
|
||||
IPAddress localIPAddress(_getResponseMulticastInterface());
|
||||
|
||||
IPAddress localIPAddress(m_pUDPContext->getInputNetif()->ip_addr);
|
||||
if (((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == localIPAddress)
|
||||
{
|
||||
// SAME IP address -> We've received an old message from ourselfs (same IP)
|
||||
@ -1221,9 +1214,7 @@ bool MDNSResponder::_updateProbeStatus(void)
|
||||
|
||||
//
|
||||
// Probe host domain
|
||||
if ((ProbingStatus_ReadyToStart == m_HostProbeInformation.m_ProbingStatus) && // Ready to get started AND
|
||||
//TODO: Fix the following to allow Ethernet shield or other interfaces
|
||||
(_getResponseMulticastInterface() != IPAddress())) // Has IP address
|
||||
if (ProbingStatus_ReadyToStart == m_HostProbeInformation.m_ProbingStatus)
|
||||
{
|
||||
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
|
||||
#ifdef MDNS_IP4_SUPPORT
|
||||
stcMDNS_RRDomain reverseIP4Domain;
|
||||
if ((_buildDomainForReverseIP4(_getResponseMulticastInterface(), reverseIP4Domain)) &&
|
||||
(p_RRHeader.m_Domain == reverseIP4Domain))
|
||||
for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next)
|
||||
{
|
||||
// Reverse domain match
|
||||
u8ReplyMask |= ContentFlag_PTR_IP4;
|
||||
if (netif_is_up(pNetIf))
|
||||
{
|
||||
if ((_buildDomainForReverseIP4(pNetIf->ip_addr, reverseIP4Domain)) &&
|
||||
(p_RRHeader.m_Domain == reverseIP4Domain))
|
||||
{
|
||||
// Reverse domain match
|
||||
u8ReplyMask |= ContentFlag_PTR_IP4;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef MDNS_IP6_SUPPORT
|
||||
|
@ -168,31 +168,23 @@ bool MDNSResponder::_allocUDPContext(void)
|
||||
{
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.println("[MDNSResponder] _allocUDPContext"););
|
||||
|
||||
bool bResult = false;
|
||||
|
||||
_releaseUDPContext();
|
||||
_joinMulticastGroups();
|
||||
|
||||
#ifdef MDNS_IP4_SUPPORT
|
||||
ip_addr_t multicast_addr = DNS_MQUERY_IPV4_GROUP_INIT;
|
||||
#endif
|
||||
#ifdef MDNS_IP6_SUPPORT
|
||||
//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->ref();
|
||||
|
||||
if (m_pUDPContext->listen(IP4_ADDR_ANY, DNS_MQUERY_PORT))
|
||||
{
|
||||
m_pUDPContext = new UdpContext;
|
||||
m_pUDPContext->ref();
|
||||
|
||||
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);
|
||||
}
|
||||
m_pUDPContext->setMulticastTTL(MDNS_MULTICAST_TTL);
|
||||
m_pUDPContext->onRx(std::bind(&MDNSResponder::_callProcess, this));
|
||||
}
|
||||
return bResult;
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -205,6 +197,7 @@ bool MDNSResponder::_releaseUDPContext(void)
|
||||
{
|
||||
m_pUDPContext->unref();
|
||||
m_pUDPContext = 0;
|
||||
_leaveMulticastGroups();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2408,12 +2408,25 @@ bool MDNSResponder::stcMDNSSendParameter::clear(void)
|
||||
delete m_pQuestions;
|
||||
m_pQuestions = pNext;
|
||||
}
|
||||
|
||||
return clearCachedNames();;
|
||||
}
|
||||
/*
|
||||
MDNSResponder::stcMDNSSendParameter::clear cached names
|
||||
*/
|
||||
bool MDNSResponder::stcMDNSSendParameter::clearCachedNames(void)
|
||||
{
|
||||
|
||||
m_u16Offset = 0;
|
||||
|
||||
while (m_pDomainCacheItems)
|
||||
{
|
||||
stcDomainCacheItem* pNext = m_pDomainCacheItems->m_pNext;
|
||||
delete m_pDomainCacheItems;
|
||||
m_pDomainCacheItems = pNext;
|
||||
}
|
||||
m_pDomainCacheItems = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -89,8 +89,8 @@ bool MDNSResponder::_sendMDNSMessage(MDNSResponder::stcMDNSSendParameter& p_rSen
|
||||
});
|
||||
IPAddress ipRemote;
|
||||
ipRemote = m_pUDPContext->getRemoteAddress();
|
||||
bResult = ((_prepareMDNSMessage(p_rSendParameter, _getResponseMulticastInterface())) &&
|
||||
(m_pUDPContext->send(ipRemote, m_pUDPContext->getRemotePort())));
|
||||
bResult = ((_prepareMDNSMessage(p_rSendParameter, m_pUDPContext->getInputNetif()->ip_addr)) &&
|
||||
(m_pUDPContext->sendTimeout(ipRemote, m_pUDPContext->getRemotePort(), MDNS_UDPCONTEXT_TIMEOUT)));
|
||||
}
|
||||
else // Multicast response
|
||||
{
|
||||
@ -121,25 +121,32 @@ bool MDNSResponder::_sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParamet
|
||||
|
||||
bool bResult = false;
|
||||
|
||||
IPAddress fromIPAddress;
|
||||
fromIPAddress = _getResponseMulticastInterface();
|
||||
m_pUDPContext->setMulticastInterface(fromIPAddress);
|
||||
for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next)
|
||||
{
|
||||
if (netif_is_up(pNetIf))
|
||||
{
|
||||
IPAddress fromIPAddress;
|
||||
//fromIPAddress = _getResponseMulticastInterface();
|
||||
fromIPAddress = pNetIf->ip_addr;
|
||||
m_pUDPContext->setMulticastInterface(fromIPAddress);
|
||||
|
||||
#ifdef MDNS_IP4_SUPPORT
|
||||
IPAddress toMulticastAddress(DNS_MQUERY_IPV4_GROUP_INIT);
|
||||
IPAddress toMulticastAddress(DNS_MQUERY_IPV4_GROUP_INIT);
|
||||
#endif
|
||||
#ifdef MDNS_IP6_SUPPORT
|
||||
//TODO: set multicast address
|
||||
IPAddress toMulticastAddress(DNS_MQUERY_IPV6_GROUP_INIT);
|
||||
//TODO: set multicast address
|
||||
IPAddress toMulticastAddress(DNS_MQUERY_IPV6_GROUP_INIT);
|
||||
#endif
|
||||
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)) &&
|
||||
(m_pUDPContext->send(toMulticastAddress, DNS_MQUERY_PORT)));
|
||||
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)) &&
|
||||
(m_pUDPContext->sendTimeout(toMulticastAddress, DNS_MQUERY_PORT, MDNS_UDPCONTEXT_TIMEOUT)));
|
||||
|
||||
DEBUG_EX_ERR(if (!bResult)
|
||||
{
|
||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage_Multicast: FAILED!\n"));
|
||||
});
|
||||
DEBUG_EX_ERR(if (!bResult)
|
||||
{
|
||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage_Multicast: FAILED!\n"));
|
||||
});
|
||||
}
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
|
||||
@ -157,6 +164,7 @@ bool MDNSResponder::_prepareMDNSMessage(MDNSResponder::stcMDNSSendParameter& p_r
|
||||
{
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _prepareMDNSMessage\n")););
|
||||
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
|
||||
stcMDNS_MsgHeader msgHeader(p_rSendParameter.m_u16ID, p_rSendParameter.m_bResponse, 0, p_rSendParameter.m_bAuthorative);
|
||||
|
@ -42,7 +42,8 @@ void setup() {
|
||||
"WL_CONNECTED = 3\n"
|
||||
"WL_CONNECT_FAILED = 4\n"
|
||||
"WL_CONNECTION_LOST = 5\n"
|
||||
"WL_DISCONNECTED = 6\n"
|
||||
"WL_WRONG_PASSWORD = 6\n"
|
||||
"WL_DISCONNECTED = 7\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
187
tests/device/test_spi_flash/test_spi_flash.ino
Normal file
187
tests/device/test_spi_flash/test_spi_flash.ino
Normal 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 ()
|
||||
{
|
||||
}
|
@ -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(){}
|
||||
|
@ -174,6 +174,7 @@ FLAGS += -DHTTPCLIENT_1_1_COMPATIBLE=0
|
||||
FLAGS += -DLWIP_IPV6=0
|
||||
FLAGS += -DHOST_MOCK=1
|
||||
FLAGS += -DNONOSDK221=1
|
||||
FLAGS += -DF_CPU=80000000
|
||||
FLAGS += $(MKFLAGS)
|
||||
FLAGS += -Wimplicit-fallthrough=2 # allow "// fall through" comments to stop spurious warnings
|
||||
FLAGS += $(USERCFLAGS)
|
||||
@ -267,6 +268,7 @@ ARDUINO_LIBS := \
|
||||
IPAddress.cpp \
|
||||
Updater.cpp \
|
||||
base64.cpp \
|
||||
LwipIntfCB.cpp \
|
||||
) \
|
||||
$(addprefix ../../libraries/ESP8266WiFi/src/,\
|
||||
ESP8266WiFi.cpp \
|
||||
|
@ -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
|
@ -56,8 +56,6 @@ const char* fspath = nullptr;
|
||||
|
||||
static struct termios initial_settings;
|
||||
|
||||
std::map<String,String> mockArgs;
|
||||
|
||||
int mockverbose (const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@ -137,8 +135,6 @@ void help (const char* argv0, int exitcode)
|
||||
"\t-S - spiffs 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-K - key\n"
|
||||
"\t-V - value\n"
|
||||
"\tgeneral:\n"
|
||||
"\t-c - ignore CTRL-C (send it via Serial)\n"
|
||||
"\t-f - no throttle (possibly 100%%CPU)\n"
|
||||
@ -162,8 +158,6 @@ static struct option options[] =
|
||||
{ "spiffskb", required_argument, NULL, 'S' },
|
||||
{ "littlefskb", required_argument, NULL, 'L' },
|
||||
{ "portshifter", required_argument, NULL, 's' },
|
||||
{ "key", required_argument, NULL, 'K' },
|
||||
{ "value", required_argument, NULL, 'V' },
|
||||
{ "once", no_argument, NULL, '1' },
|
||||
};
|
||||
|
||||
@ -215,11 +209,10 @@ int main (int argc, char* const argv [])
|
||||
mock_port_shifter = 0;
|
||||
else
|
||||
mock_port_shifter = MOCK_PORT_SHIFTER;
|
||||
String key;
|
||||
|
||||
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)
|
||||
break;
|
||||
switch (n)
|
||||
@ -260,12 +253,6 @@ int main (int argc, char* const argv [])
|
||||
case 'T':
|
||||
serial_timestamp = true;
|
||||
break;
|
||||
case 'K':
|
||||
key = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
mockArgs[key] = optarg;
|
||||
break;
|
||||
case '1':
|
||||
run_once = true;
|
||||
break;
|
||||
|
@ -159,7 +159,15 @@ FlashMode_t EspClass::magicFlashChipMode(uint8_t byte)
|
||||
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)data;
|
||||
@ -175,6 +183,14 @@ bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size)
|
||||
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) {
|
||||
switch(byte & 0x0F) {
|
||||
case 0x0: // 4 Mbit (512KB)
|
||||
|
@ -53,16 +53,6 @@ int ets_printf (const char* fmt, ...)
|
||||
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_del_ref() { }
|
||||
void stack_thunk_repaint() { }
|
||||
@ -78,3 +68,13 @@ void stack_thunk_dump_stack() { }
|
||||
#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);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <cerrno>
|
||||
#include "flash_hal_mock.h"
|
||||
|
||||
#define LITTLEFS_FILE_NAME "littlefs.bin"
|
||||
|
@ -30,6 +30,7 @@
|
||||
*/
|
||||
|
||||
#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 A0 0
|
||||
#define LED_BUILTIN 0
|
||||
#define F_CPU 80000000
|
||||
#define LWIP_OPEN_SRC
|
||||
#define TCP_MSS 536
|
||||
#define LWIP_FEATURES 1
|
||||
@ -54,28 +54,23 @@
|
||||
#define D7 7
|
||||
#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>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
//#include <stdlib_noniso.h>
|
||||
// TODO: #include <stdlib_noniso.h> ?
|
||||
char* itoa (int 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 strlcpy(char *dst, const char *src, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// exotic typedefs used in the sdk
|
||||
|
||||
#include <stdint.h>
|
||||
@ -91,9 +86,6 @@ uint32_t esp_get_cycle_count();
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
#define RANDOM_REG32 ((uint32_t)random())
|
||||
|
||||
// net tweak
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <cerrno>
|
||||
|
||||
#include "flash_hal_mock.h"
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#define FLASH_SECTOR_SIZE 0x1000
|
||||
#define FLASH_BLOCK_SIZE 0x10000
|
||||
#define FLASH_PAGE_SIZE 0x100
|
||||
#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
|
||||
|
@ -74,6 +74,13 @@ def main():
|
||||
outdir = os.path.dirname(args.out)
|
||||
if not os.path.exists(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:
|
||||
f.write(val)
|
||||
return 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user