mirror of https://github.com/arendst/Tasmota.git
Merge branch 'development' into teleinfo-dev
This commit is contained in:
commit
8f3821d862
|
@ -77,6 +77,7 @@
|
|||
| USE_MAX31855 | - | - | - | - | x | - | - |
|
||||
| USE_MAX31865 | - | - | - | - | - | - | - |
|
||||
| USE_THERMOSTAT | - | - | - | - | - | - | - |
|
||||
| USE_LMT01 | - | - | - | - | x | - | - |
|
||||
| | | | | | | | |
|
||||
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
||||
| USE_I2C | - | - | x | x | x | - | x |
|
||||
|
@ -181,3 +182,4 @@
|
|||
|-----------------------|---------|-------|--------|-----|---------|----|---------|--------|--------
|
||||
| USE_MI_ESP32 | - | - | - | - | - | - | - | - |
|
||||
| USE_WEBCAM | - | - | - | - | - | - | - | x |
|
||||
| USE_ETHERNET | - | - | - | - | - | - | - | - |
|
||||
|
|
|
@ -72,4 +72,5 @@ Index | Define | Driver | Device | Address(es) | Description
|
|||
48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor
|
||||
49 | USE_VEML6075 | xsns_70 | VEML6075 | 0x10 | UVA/UVB/UVINDEX Sensor
|
||||
50 | USE_VEML7700 | xsns_71 | VEML7700 | 0x10 | Ambient light intensity sensor
|
||||
51 | USE_MCP9808 | xsns_72 | MCP9808 | 0x18 - 0x1F | Temperature sensor
|
||||
51 | USE_MCP9808 | xsns_72 | MCP9808 | 0x18 - 0x1F | Temperature sensor
|
||||
52 | USE_HP303B | xsns_73 | HP303B | 0x76 - 0x77 | Pressure and temperature sensor
|
|
@ -52,19 +52,22 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
|||
|
||||
## Changelog
|
||||
|
||||
### Version 8.3.1.2
|
||||
### Version 8.3.1.6
|
||||
|
||||
- Created Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff
|
||||
- Added Library to be used for decoding Teleinfo (French Metering Smart Meter)
|
||||
- Change IRremoteESP8266 library updated to v2.7.7
|
||||
- Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519)
|
||||
- Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]``
|
||||
- Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]``
|
||||
- Change ESP32 USER GPIO template representation decreasing template message size
|
||||
- Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT
|
||||
- Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset``
|
||||
- Fix escape of non-JSON received serial data (#8329)
|
||||
- Add command ``Rule0`` to change global rule parameters
|
||||
- Add command ``Time 4`` to display timestamp using milliseconds (#8537)
|
||||
- Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616)
|
||||
- Add command ``Module2`` to configure fallback module on fast reboot (#8464)
|
||||
- Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491)
|
||||
- Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3``
|
||||
- Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300)
|
||||
- Add more functionality to ``Switchmode`` 11 and 12 (#8450)
|
||||
- Add wildcard pattern ``?`` for JSON matching in rules
|
||||
|
@ -78,3 +81,10 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
|||
- Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139)
|
||||
- Add support for up to eight MCP9808 temperature sensors by device111 (#8594)
|
||||
- Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175)
|
||||
- Add initial support for Telegram bot (#8619)
|
||||
- Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638)
|
||||
- Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet
|
||||
- Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff
|
||||
- Add Library to be used for decoding Teleinfo (French Metering Smart Meter)
|
||||
- Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON
|
||||
- Add support for single wire LMT01 temperature Sensor by justifiably (#8713)
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Arduino library for the HP303B
|
||||
### Installation
|
||||
- Clone this repository or download&unzip [zip file](https://github.com/wemos/LOLIN_HP303B_Library/archive/master.zip) into Arduino/libraries
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
#include <LOLIN_HP303B.h>
|
||||
|
||||
// HP303B Opject
|
||||
LOLIN_HP303B HP303BPressureSensor = LOLIN_HP303B();
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
//Call begin to initialize HP303BPressureSensor
|
||||
//The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given.
|
||||
//HP303BPressureSensor.begin(Wire, 0x76);
|
||||
//Use the commented line below instead to use the default I2C address.
|
||||
HP303BPressureSensor.begin();
|
||||
|
||||
//temperature measure rate (value from 0 to 7)
|
||||
//2^temp_mr temperature measurement results per second
|
||||
int16_t temp_mr = 2;
|
||||
//temperature oversampling rate (value from 0 to 7)
|
||||
//2^temp_osr internal temperature measurements per result
|
||||
//A higher value increases precision
|
||||
int16_t temp_osr = 2;
|
||||
//pressure measure rate (value from 0 to 7)
|
||||
//2^prs_mr pressure measurement results per second
|
||||
int16_t prs_mr = 2;
|
||||
//pressure oversampling rate (value from 0 to 7)
|
||||
//2^prs_osr internal pressure measurements per result
|
||||
//A higher value increases precision
|
||||
int16_t prs_osr = 2;
|
||||
//startMeasureBothCont enables background mode
|
||||
//temperature and pressure ar measured automatically
|
||||
//High precision and hgh measure rates at the same time are not available.
|
||||
//Consult Datasheet (or trial and error) for more information
|
||||
int16_t ret = HP303BPressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr);
|
||||
//Use one of the commented lines below instead to measure only temperature or pressure
|
||||
//int16_t ret = HP303BPressureSensor.startMeasureTempCont(temp_mr, temp_osr);
|
||||
//int16_t ret = HP303BPressureSensor.startMeasurePressureCont(prs_mr, prs_osr);
|
||||
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
Serial.print("Init FAILED! ret = ");
|
||||
Serial.println(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Init complete!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
unsigned char pressureCount = 20;
|
||||
int32_t pressure[pressureCount];
|
||||
unsigned char temperatureCount = 20;
|
||||
int32_t temperature[temperatureCount];
|
||||
|
||||
//This function writes the results of continuous measurements to the arrays given as parameters
|
||||
//The parameters temperatureCount and pressureCount should hold the sizes of the arrays temperature and pressure when the function is called
|
||||
//After the end of the function, temperatureCount and pressureCount hold the numbers of values written to the arrays
|
||||
//Note: The HP303B cannot save more than 32 results. When its result buffer is full, it won't save any new measurement results
|
||||
int16_t ret = HP303BPressureSensor.getContResults(temperature, temperatureCount, pressure, pressureCount);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.print("FAIL! ret = ");
|
||||
Serial.println(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.print(temperatureCount);
|
||||
Serial.println(" temperature values found: ");
|
||||
for (int16_t i = 0; i < temperatureCount; i++)
|
||||
{
|
||||
Serial.print(temperature[i]);
|
||||
Serial.println(" degrees of Celsius");
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
Serial.print(pressureCount);
|
||||
Serial.println(" pressure values found: ");
|
||||
for (int16_t i = 0; i < pressureCount; i++)
|
||||
{
|
||||
Serial.print(pressure[i]);
|
||||
Serial.println(" Pascal");
|
||||
}
|
||||
}
|
||||
|
||||
//Wait some time, so that the HP303B can refill its buffer
|
||||
delay(10000);
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
#include <LOLIN_HP303B.h>
|
||||
|
||||
// HP303B Opject
|
||||
LOLIN_HP303B HP303BPressureSensor;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
|
||||
//Call begin to initialize HP303BPressureSensor
|
||||
//The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given.
|
||||
//HP303BPressureSensor.begin(Wire, 0x76);
|
||||
//Use the commented line below instead of the one above to use the default I2C address.
|
||||
//if you are using the Pressure 3 click Board, you need 0x76
|
||||
HP303BPressureSensor.begin();
|
||||
|
||||
Serial.println("Init complete!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
int32_t temperature;
|
||||
int32_t pressure;
|
||||
int16_t oversampling = 7;
|
||||
int16_t ret;
|
||||
Serial.println();
|
||||
|
||||
//lets the HP303B perform a Single temperature measurement with the last (or standard) configuration
|
||||
//The result will be written to the paramerter temperature
|
||||
//ret = HP303BPressureSensor.measureTempOnce(temperature);
|
||||
//the commented line below does exactly the same as the one above, but you can also config the precision
|
||||
//oversampling can be a value from 0 to 7
|
||||
//the HP303B will perform 2^oversampling internal temperature measurements and combine them to one result with higher precision
|
||||
//measurements with higher precision take more time, consult datasheet for more information
|
||||
ret = HP303BPressureSensor.measureTempOnce(temperature, oversampling);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
//Something went wrong.
|
||||
//Look at the library code for more information about return codes
|
||||
Serial.print("FAIL! ret = ");
|
||||
Serial.println(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("Temperature: ");
|
||||
Serial.print(temperature);
|
||||
Serial.println(" degrees of Celsius");
|
||||
}
|
||||
|
||||
//Pressure measurement behaves like temperature measurement
|
||||
//ret = HP303BPressureSensor.measurePressureOnce(pressure);
|
||||
ret = HP303BPressureSensor.measurePressureOnce(pressure, oversampling);
|
||||
if (ret != 0)
|
||||
{
|
||||
//Something went wrong.
|
||||
//Look at the library code for more information about return codes
|
||||
Serial.print("FAIL! ret = ");
|
||||
Serial.println(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("Pressure: ");
|
||||
Serial.print(pressure);
|
||||
Serial.println(" Pascal");
|
||||
}
|
||||
|
||||
//Wait some time
|
||||
delay(500);
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
#include <LOLIN_HP303B.h>
|
||||
|
||||
// HP303B Opject
|
||||
LOLIN_HP303B HP303BPressureSensor = LOLIN_HP303B();
|
||||
|
||||
void onFifoFull();
|
||||
|
||||
const unsigned char pressureLength = 50;
|
||||
unsigned char pressureCount = 0;
|
||||
int32_t pressure[pressureLength];
|
||||
unsigned char temperatureCount = 0;
|
||||
const unsigned char temperatureLength = 50;
|
||||
int32_t temperature[temperatureLength];
|
||||
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
//Call begin to initialize HP303BPressureSensor
|
||||
//The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given.
|
||||
//HP303BPressureSensor.begin(Wire, 0x76);
|
||||
//Use the commented line below instead to use the default I2C address.
|
||||
HP303BPressureSensor.begin();
|
||||
|
||||
int16_t ret = HP303BPressureSensor.setInterruptPolarity(1);
|
||||
ret = HP303BPressureSensor.setInterruptSources(1, 0, 0);
|
||||
//clear interrupt flag by reading
|
||||
HP303BPressureSensor.getIntStatusFifoFull();
|
||||
|
||||
//initialization of Interrupt for Controller unit
|
||||
//SDO pin of HP303B has to be connected with interrupt pin
|
||||
int16_t interruptPin = 3;
|
||||
pinMode(interruptPin, INPUT);
|
||||
attachInterrupt(digitalPinToInterrupt(interruptPin), onFifoFull, RISING);
|
||||
|
||||
//start of a continuous measurement just like before
|
||||
int16_t temp_mr = 3;
|
||||
int16_t temp_osr = 2;
|
||||
int16_t prs_mr = 1;
|
||||
int16_t prs_osr = 3;
|
||||
ret = HP303BPressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr);
|
||||
if (ret != 0)
|
||||
{
|
||||
Serial.print("Init FAILED! ret = ");
|
||||
Serial.println(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Init complete!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
//do other stuff
|
||||
Serial.println("loop running");
|
||||
delay(500);
|
||||
|
||||
|
||||
//if result arrays are full
|
||||
//This could also be in the interrupt handler, but it would take too much time for a proper ISR
|
||||
if (pressureCount == pressureLength && temperatureCount == temperatureLength)
|
||||
{
|
||||
//print results
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.print(temperatureCount);
|
||||
Serial.println(" temperature values found: ");
|
||||
for (int16_t i = 0; i < temperatureCount; i++)
|
||||
{
|
||||
Serial.print(temperature[i]);
|
||||
Serial.println(" degrees of Celsius");
|
||||
}
|
||||
Serial.println();
|
||||
Serial.print(pressureCount);
|
||||
Serial.println(" pressure values found: ");
|
||||
for (int16_t i = 0; i < pressureCount; i++)
|
||||
{
|
||||
Serial.print(pressure[i]);
|
||||
Serial.println(" Pascal");
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
//reset result counters
|
||||
pressureCount = 0;
|
||||
temperatureCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//interrupt handler
|
||||
void onFifoFull()
|
||||
{
|
||||
//message for debugging
|
||||
Serial.println("Interrupt handler called");
|
||||
|
||||
//clear interrupt flag by reading
|
||||
HP303BPressureSensor.getIntStatusFifoFull();
|
||||
|
||||
//calculate the number of free indexes in the result arrays
|
||||
unsigned char prs_freespace = pressureLength - pressureCount;
|
||||
unsigned char temp_freespace = temperatureLength - temperatureCount;
|
||||
//read the results from HP303B, new results will be added at the end of the arrays
|
||||
HP303BPressureSensor.getContResults(&temperature[temperatureCount], temp_freespace, &pressure[pressureCount], prs_freespace);
|
||||
//after reading the result counters are increased by the amount of new results
|
||||
pressureCount += prs_freespace;
|
||||
temperatureCount += temp_freespace;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#######################################
|
||||
# Syntax Coloring Map For DHT12
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
DHT12 KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
get KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
cTemp LITERAL1
|
||||
fTemp LITERAL1
|
||||
humidity LITERAL1
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
name=LOLIN_HP303B
|
||||
version=1.0.0
|
||||
author=WEMOS.CC <support@wemos.cc>
|
||||
maintainer=WEMOS.CC
|
||||
sentence=Library for the <a href="https://www.wemos.cc">HP303B.</a>.
|
||||
paragraph=LOLIN HP303B
|
||||
category=Device Control
|
||||
url=https://github.com/wemos/LOLIN_HP303B_Library
|
||||
architectures=*
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,146 @@
|
|||
#ifndef __LOLIN_HP303B_H
|
||||
#define __LOLIN_HP303B_H
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include "util/hp303b_consts.h"
|
||||
|
||||
class LOLIN_HP303B
|
||||
{
|
||||
public:
|
||||
//constructor
|
||||
LOLIN_HP303B(void);
|
||||
//destructor
|
||||
~LOLIN_HP303B(void);
|
||||
//begin
|
||||
uint8_t begin(TwoWire &bus, uint8_t slaveAddress);
|
||||
uint8_t begin(uint8_t slaveAddress=HP303B__STD_SLAVE_ADDRESS);
|
||||
uint8_t begin(SPIClass &bus, int32_t chipSelect);
|
||||
uint8_t begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire);
|
||||
//end
|
||||
void end(void);
|
||||
|
||||
//general
|
||||
uint8_t getProductId(void);
|
||||
uint8_t getRevisionId(void);
|
||||
|
||||
//Idle Mode
|
||||
int16_t standby(void);
|
||||
|
||||
//Command Mode
|
||||
int16_t measureTempOnce(float &result);
|
||||
int16_t measureTempOnce(float &result, uint8_t slaveAddress);
|
||||
int16_t measureTempOnce(float &result, uint8_t slaveAddress, uint8_t oversamplingRate);
|
||||
int16_t startMeasureTempOnce(void);
|
||||
int16_t startMeasureTempOnce(uint8_t oversamplingRate);
|
||||
int16_t measurePressureOnce(float &result);
|
||||
int16_t measurePressureOnce(float &result, uint8_t slaveAddress);
|
||||
int16_t measurePressureOnce(float &result, uint8_t slaveAddress, uint8_t oversamplingRate);
|
||||
int16_t startMeasurePressureOnce(void);
|
||||
int16_t startMeasurePressureOnce(uint8_t oversamplingRate);
|
||||
int16_t getSingleResult(float &result);
|
||||
|
||||
//Background Mode
|
||||
int16_t startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate);
|
||||
int16_t startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate);
|
||||
int16_t startMeasureBothCont(uint8_t tempMr, uint8_t tempOsr, uint8_t prsMr, uint8_t prsOsr);
|
||||
int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount);
|
||||
|
||||
//Interrupt Control
|
||||
int16_t setInterruptPolarity(uint8_t polarity);
|
||||
int16_t setInterruptSources(uint8_t fifoFull, uint8_t tempReady, uint8_t prsReady);
|
||||
int16_t getIntStatusFifoFull(void);
|
||||
int16_t getIntStatusTempReady(void);
|
||||
int16_t getIntStatusPrsReady(void);
|
||||
|
||||
//function to fix a hardware problem on some devices
|
||||
int16_t correctTemp(void);
|
||||
|
||||
private:
|
||||
//scaling factor table
|
||||
static const int32_t scaling_facts[HP303B__NUM_OF_SCAL_FACTS];
|
||||
|
||||
//enum for operating mode
|
||||
enum Mode
|
||||
{
|
||||
IDLE = 0x00,
|
||||
CMD_PRS = 0x01,
|
||||
CMD_TEMP = 0x02,
|
||||
INVAL_OP_CMD_BOTH = 0x03, //invalid
|
||||
INVAL_OP_CONT_NONE = 0x04, //invalid
|
||||
CONT_PRS = 0x05,
|
||||
CONT_TMP = 0x06,
|
||||
CONT_BOTH = 0x07
|
||||
};
|
||||
Mode m_opMode;
|
||||
|
||||
//flags
|
||||
uint8_t m_initFail;
|
||||
uint8_t m_productID;
|
||||
uint8_t m_revisionID;
|
||||
|
||||
//settings
|
||||
uint8_t m_tempMr;
|
||||
uint8_t m_tempOsr;
|
||||
uint8_t m_prsMr;
|
||||
uint8_t m_prsOsr;
|
||||
uint8_t m_tempSensor;
|
||||
|
||||
//compensation coefficients
|
||||
int32_t m_c0Half;
|
||||
int32_t m_c1;
|
||||
int32_t m_c00;
|
||||
int32_t m_c10;
|
||||
int32_t m_c01;
|
||||
int32_t m_c11;
|
||||
int32_t m_c20;
|
||||
int32_t m_c21;
|
||||
int32_t m_c30;
|
||||
//last measured scaled temperature
|
||||
//(necessary for pressure compensation)
|
||||
double m_lastTempScal;
|
||||
|
||||
//bus specific
|
||||
uint8_t m_SpiI2c; //0=SPI, 1=I2C
|
||||
//used for I2C
|
||||
TwoWire *m_i2cbus;
|
||||
uint8_t m_slaveAddress;
|
||||
//used for SPI
|
||||
SPIClass *m_spibus;
|
||||
int32_t m_chipSelect;
|
||||
uint8_t m_threeWire;
|
||||
|
||||
//measurement
|
||||
uint8_t init(void);
|
||||
int16_t readcoeffs(void);
|
||||
int16_t setOpMode(uint8_t background, uint8_t temperature, uint8_t pressure);
|
||||
int16_t setOpMode(uint8_t opMode);
|
||||
int16_t configTemp(uint8_t temp_mr, uint8_t temp_osr);
|
||||
int16_t configPressure(uint8_t prs_mr, uint8_t prs_osr);
|
||||
uint16_t calcBusyTime(uint16_t temp_rate, uint16_t temp_osr);
|
||||
int16_t getTemp(float *result);
|
||||
int16_t getPressure(float *result);
|
||||
int16_t getFIFOvalue(float *value);
|
||||
float calcTemp(float raw);
|
||||
float calcPressure(float raw);
|
||||
|
||||
//bus specific
|
||||
int16_t readByte(uint8_t regAddress);
|
||||
int16_t readByteSPI(uint8_t regAddress);
|
||||
int16_t readBlock(uint8_t regAddress, uint8_t length, uint8_t *buffer);
|
||||
int16_t readBlockSPI(uint8_t regAddress, uint8_t length, uint8_t *readbuffer);
|
||||
int16_t writeByte(uint8_t regAddress, uint8_t data);
|
||||
int16_t writeByte(uint8_t regAddress, uint8_t data, uint8_t check);
|
||||
int16_t writeByteSpi(uint8_t regAddress, uint8_t data, uint8_t check);
|
||||
int16_t writeByteBitfield(uint8_t data, uint8_t regAddress, uint8_t mask, uint8_t shift);
|
||||
int16_t writeByteBitfield(uint8_t data, uint8_t regAddress, uint8_t mask, uint8_t shift, uint8_t check);
|
||||
int16_t readByteBitfield(uint8_t regAddress, uint8_t mask, uint8_t shift);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,258 @@
|
|||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __HP303B_CONSTS_H_
|
||||
#define __HP303B_CONSTS_H_
|
||||
|
||||
|
||||
//general Constants
|
||||
#define HP303B__PROD_ID 0U
|
||||
#define HP303B__STD_SLAVE_ADDRESS 0x77U
|
||||
#define HP303B__SPI_WRITE_CMD 0x00U
|
||||
#define HP303B__SPI_READ_CMD 0x80U
|
||||
#define HP303B__SPI_RW_MASK 0x80U
|
||||
#define HP303B__SPI_MAX_FREQ 100000U
|
||||
|
||||
#define HP303B__LSB 0x01U
|
||||
|
||||
#define HP303B__TEMP_STD_MR 2U
|
||||
#define HP303B__TEMP_STD_OSR 3U
|
||||
#define HP303B__PRS_STD_MR 2U
|
||||
#define HP303B__PRS_STD_OSR 3U
|
||||
#define HP303B__OSR_SE 3U
|
||||
//we use 0.1 mS units for time calculations, so 10 units are one millisecond
|
||||
#define HP303B__BUSYTIME_SCALING 10U
|
||||
// DPS310 has 10 milliseconds of spare time for each synchronous measurement / per second for asynchronous measurements
|
||||
// this is for error prevention on friday-afternoon-products :D
|
||||
// you can set it to 0 if you dare, but there is no warranty that it will still work
|
||||
#define HP303B__BUSYTIME_FAILSAFE 10U
|
||||
#define HP303B__MAX_BUSYTIME ((1000U-HP303B__BUSYTIME_FAILSAFE)*HP303B__BUSYTIME_SCALING)
|
||||
#define HP303B__NUM_OF_SCAL_FACTS 8
|
||||
|
||||
#define HP303B__SUCCEEDED 0
|
||||
#define HP303B__FAIL_UNKNOWN -1
|
||||
#define HP303B__FAIL_INIT_FAILED -2
|
||||
#define HP303B__FAIL_TOOBUSY -3
|
||||
#define HP303B__FAIL_UNFINISHED -4
|
||||
|
||||
|
||||
//Constants for register manipulation
|
||||
//SPI mode (3 or 4 wire)
|
||||
#define HP303B__REG_ADR_SPI3W 0x09U
|
||||
#define HP303B__REG_CONTENT_SPI3W 0x01U
|
||||
|
||||
|
||||
//product id
|
||||
#define HP303B__REG_INFO_PROD_ID HP303B__REG_ADR_PROD_ID, \
|
||||
HP303B__REG_MASK_PROD_ID, \
|
||||
HP303B__REG_SHIFT_PROD_ID
|
||||
#define HP303B__REG_ADR_PROD_ID 0x0DU
|
||||
#define HP303B__REG_MASK_PROD_ID 0x0FU
|
||||
#define HP303B__REG_SHIFT_PROD_ID 0U
|
||||
|
||||
//revision id
|
||||
#define HP303B__REG_INFO_REV_ID HP303B__REG_ADR_REV_ID, \
|
||||
HP303B__REG_MASK_REV_ID, \
|
||||
HP303B__REG_SHIFT_REV_ID
|
||||
#define HP303B__REG_ADR_REV_ID 0x0DU
|
||||
#define HP303B__REG_MASK_REV_ID 0xF0U
|
||||
#define HP303B__REG_SHIFT_REV_ID 4U
|
||||
|
||||
//operating mode
|
||||
#define HP303B__REG_INFO_OPMODE HP303B__REG_ADR_OPMODE, \
|
||||
HP303B__REG_MASK_OPMODE, \
|
||||
HP303B__REG_SHIFT_OPMODE
|
||||
#define HP303B__REG_ADR_OPMODE 0x08U
|
||||
#define HP303B__REG_MASK_OPMODE 0x07U
|
||||
#define HP303B__REG_SHIFT_OPMODE 0U
|
||||
|
||||
|
||||
//temperature measure rate
|
||||
#define HP303B__REG_INFO_TEMP_MR HP303B__REG_ADR_TEMP_MR, \
|
||||
HP303B__REG_MASK_TEMP_MR, \
|
||||
HP303B__REG_SHIFT_TEMP_MR
|
||||
#define HP303B__REG_ADR_TEMP_MR 0x07U
|
||||
#define HP303B__REG_MASK_TEMP_MR 0x70U
|
||||
#define HP303B__REG_SHIFT_TEMP_MR 4U
|
||||
|
||||
//temperature oversampling rate
|
||||
#define HP303B__REG_INFO_TEMP_OSR HP303B__REG_ADR_TEMP_OSR, \
|
||||
HP303B__REG_MASK_TEMP_OSR, \
|
||||
HP303B__REG_SHIFT_TEMP_OSR
|
||||
#define HP303B__REG_ADR_TEMP_OSR 0x07U
|
||||
#define HP303B__REG_MASK_TEMP_OSR 0x07U
|
||||
#define HP303B__REG_SHIFT_TEMP_OSR 0U
|
||||
|
||||
//temperature sensor
|
||||
#define HP303B__REG_INFO_TEMP_SENSOR HP303B__REG_ADR_TEMP_SENSOR, \
|
||||
HP303B__REG_MASK_TEMP_SENSOR, \
|
||||
HP303B__REG_SHIFT_TEMP_SENSOR
|
||||
#define HP303B__REG_ADR_TEMP_SENSOR 0x07U
|
||||
#define HP303B__REG_MASK_TEMP_SENSOR 0x80U
|
||||
#define HP303B__REG_SHIFT_TEMP_SENSOR 7U
|
||||
|
||||
//temperature sensor recommendation
|
||||
#define HP303B__REG_INFO_TEMP_SENSORREC HP303B__REG_ADR_TEMP_SENSORREC, \
|
||||
HP303B__REG_MASK_TEMP_SENSORREC, \
|
||||
HP303B__REG_SHIFT_TEMP_SENSORREC
|
||||
#define HP303B__REG_ADR_TEMP_SENSORREC 0x28U
|
||||
#define HP303B__REG_MASK_TEMP_SENSORREC 0x80U
|
||||
#define HP303B__REG_SHIFT_TEMP_SENSORREC 7U
|
||||
|
||||
//temperature shift enable (if temp_osr>3)
|
||||
#define HP303B__REG_INFO_TEMP_SE HP303B__REG_ADR_TEMP_SE, \
|
||||
HP303B__REG_MASK_TEMP_SE, \
|
||||
HP303B__REG_SHIFT_TEMP_SE
|
||||
#define HP303B__REG_ADR_TEMP_SE 0x09U
|
||||
#define HP303B__REG_MASK_TEMP_SE 0x08U
|
||||
#define HP303B__REG_SHIFT_TEMP_SE 3U
|
||||
|
||||
|
||||
//pressure measure rate
|
||||
#define HP303B__REG_INFO_PRS_MR HP303B__REG_ADR_PRS_MR, \
|
||||
HP303B__REG_MASK_PRS_MR, \
|
||||
HP303B__REG_SHIFT_PRS_MR
|
||||
#define HP303B__REG_ADR_PRS_MR 0x06U
|
||||
#define HP303B__REG_MASK_PRS_MR 0x70U
|
||||
#define HP303B__REG_SHIFT_PRS_MR 4U
|
||||
|
||||
//pressure oversampling rate
|
||||
#define HP303B__REG_INFO_PRS_OSR HP303B__REG_ADR_PRS_OSR, \
|
||||
HP303B__REG_MASK_PRS_OSR, \
|
||||
HP303B__REG_SHIFT_PRS_OSR
|
||||
#define HP303B__REG_ADR_PRS_OSR 0x06U
|
||||
#define HP303B__REG_MASK_PRS_OSR 0x07U
|
||||
#define HP303B__REG_SHIFT_PRS_OSR 0U
|
||||
|
||||
//pressure shift enable (if prs_osr>3)
|
||||
#define HP303B__REG_INFO_PRS_SE HP303B__REG_ADR_PRS_SE, \
|
||||
HP303B__REG_MASK_PRS_SE, \
|
||||
HP303B__REG_SHIFT_PRS_SE
|
||||
#define HP303B__REG_ADR_PRS_SE 0x09U
|
||||
#define HP303B__REG_MASK_PRS_SE 0x04U
|
||||
#define HP303B__REG_SHIFT_PRS_SE 2U
|
||||
|
||||
|
||||
//temperature ready flag
|
||||
#define HP303B__REG_INFO_TEMP_RDY HP303B__REG_ADR_TEMP_RDY, \
|
||||
HP303B__REG_MASK_TEMP_RDY, \
|
||||
HP303B__REG_SHIFT_TEMP_RDY
|
||||
#define HP303B__REG_ADR_TEMP_RDY 0x08U
|
||||
#define HP303B__REG_MASK_TEMP_RDY 0x20U
|
||||
#define HP303B__REG_SHIFT_TEMP_RDY 5U
|
||||
|
||||
//pressure ready flag
|
||||
#define HP303B__REG_INFO_PRS_RDY HP303B__REG_ADR_PRS_RDY, \
|
||||
HP303B__REG_MASK_PRS_RDY, \
|
||||
HP303B__REG_SHIFT_PRS_RDY
|
||||
#define HP303B__REG_ADR_PRS_RDY 0x08U
|
||||
#define HP303B__REG_MASK_PRS_RDY 0x10U
|
||||
#define HP303B__REG_SHIFT_PRS_RDY 4U
|
||||
|
||||
//pressure value
|
||||
#define HP303B__REG_ADR_PRS 0x00U
|
||||
#define HP303B__REG_LEN_PRS 3U
|
||||
|
||||
//temperature value
|
||||
#define HP303B__REG_ADR_TEMP 0x03U
|
||||
#define HP303B__REG_LEN_TEMP 3U
|
||||
|
||||
//compensation coefficients
|
||||
#define HP303B__REG_ADR_COEF 0x10U
|
||||
#define HP303B__REG_LEN_COEF 18
|
||||
|
||||
|
||||
//FIFO enable
|
||||
#define HP303B__REG_INFO_FIFO_EN HP303B__REG_ADR_FIFO_EN, \
|
||||
HP303B__REG_MASK_FIFO_EN, \
|
||||
HP303B__REG_SHIFT_FIFO_EN
|
||||
#define HP303B__REG_ADR_FIFO_EN 0x09U
|
||||
#define HP303B__REG_MASK_FIFO_EN 0x02U
|
||||
#define HP303B__REG_SHIFT_FIFO_EN 1U
|
||||
|
||||
//FIFO flush
|
||||
#define HP303B__REG_INFO_FIFO_FL HP303B__REG_ADR_FIFO_EN, \
|
||||
HP303B__REG_MASK_FIFO_EN, \
|
||||
HP303B__REG_SHIFT_FIFO_EN
|
||||
#define HP303B__REG_ADR_FIFO_FL 0x0CU
|
||||
#define HP303B__REG_MASK_FIFO_FL 0x80U
|
||||
#define HP303B__REG_SHIFT_FIFO_FL 7U
|
||||
|
||||
//FIFO empty
|
||||
#define HP303B__REG_INFO_FIFO_EMPTY HP303B__REG_ADR_FIFO_EMPTY, \
|
||||
HP303B__REG_MASK_FIFO_EMPTY, \
|
||||
HP303B__REG_SHIFT_FIFO_EMPTY
|
||||
#define HP303B__REG_ADR_FIFO_EMPTY 0x0BU
|
||||
#define HP303B__REG_MASK_FIFO_EMPTY 0x01U
|
||||
#define HP303B__REG_SHIFT_FIFO_EMPTY 0U
|
||||
|
||||
//FIFO full
|
||||
#define HP303B__REG_INFO_FIFO_FULL HP303B__REG_ADR_FIFO_FULL, \
|
||||
HP303B__REG_MASK_FIFO_FULL, \
|
||||
HP303B__REG_SHIFT_FIFO_FULL
|
||||
#define HP303B__REG_ADR_FIFO_FULL 0x0BU
|
||||
#define HP303B__REG_MASK_FIFO_FULL 0x02U
|
||||
#define HP303B__REG_SHIFT_FIFO_FULL 1U
|
||||
|
||||
|
||||
//INT HL
|
||||
#define HP303B__REG_INFO_INT_HL HP303B__REG_ADR_INT_HL, \
|
||||
HP303B__REG_MASK_INT_HL, \
|
||||
HP303B__REG_SHIFT_INT_HL
|
||||
#define HP303B__REG_ADR_INT_HL 0x09U
|
||||
#define HP303B__REG_MASK_INT_HL 0x80U
|
||||
#define HP303B__REG_SHIFT_INT_HL 7U
|
||||
|
||||
//INT FIFO enable
|
||||
#define HP303B__REG_INFO_INT_EN_FIFO HP303B__REG_ADR_INT_EN_FIFO, \
|
||||
HP303B__REG_MASK_INT_EN_FIFO, \
|
||||
HP303B__REG_SHIFT_INT_EN_FIFO
|
||||
#define HP303B__REG_ADR_INT_EN_FIFO 0x09U
|
||||
#define HP303B__REG_MASK_INT_EN_FIFO 0x40U
|
||||
#define HP303B__REG_SHIFT_INT_EN_FIFO 6U
|
||||
|
||||
//INT TEMP enable
|
||||
#define HP303B__REG_INFO_INT_EN_TEMP HP303B__REG_ADR_INT_EN_TEMP, \
|
||||
HP303B__REG_MASK_INT_EN_TEMP, \
|
||||
HP303B__REG_SHIFT_INT_EN_TEMP
|
||||
#define HP303B__REG_ADR_INT_EN_TEMP 0x09U
|
||||
#define HP303B__REG_MASK_INT_EN_TEMP 0x20U
|
||||
#define HP303B__REG_SHIFT_INT_EN_TEMP 5U
|
||||
|
||||
//INT PRS enable
|
||||
#define HP303B__REG_INFO_INT_EN_PRS HP303B__REG_ADR_INT_EN_PRS, \
|
||||
HP303B__REG_MASK_INT_EN_PRS, \
|
||||
HP303B__REG_SHIFT_INT_EN_PRS
|
||||
#define HP303B__REG_ADR_INT_EN_PRS 0x09U
|
||||
#define HP303B__REG_MASK_INT_EN_PRS 0x10U
|
||||
#define HP303B__REG_SHIFT_INT_EN_PRS 4U
|
||||
|
||||
//INT FIFO flag
|
||||
#define HP303B__REG_INFO_INT_FLAG_FIFO HP303B__REG_ADR_INT_FLAG_FIFO, \
|
||||
HP303B__REG_MASK_INT_FLAG_FIFO, \
|
||||
HP303B__REG_SHIFT_INT_FLAG_FIFO
|
||||
#define HP303B__REG_ADR_INT_FLAG_FIFO 0x0AU
|
||||
#define HP303B__REG_MASK_INT_FLAG_FIFO 0x04U
|
||||
#define HP303B__REG_SHIFT_INT_FLAG_FIFO 2U
|
||||
|
||||
//INT TMP flag
|
||||
#define HP303B__REG_INFO_INT_FLAG_TEMP HP303B__REG_ADR_INT_FLAG_TEMP, \
|
||||
HP303B__REG_MASK_INT_FLAG_TEMP, \
|
||||
HP303B__REG_SHIFT_INT_FLAG_TEMP
|
||||
#define HP303B__REG_ADR_INT_FLAG_TEMP 0x0AU
|
||||
#define HP303B__REG_MASK_INT_FLAG_TEMP 0x02U
|
||||
#define HP303B__REG_SHIFT_INT_FLAG_TEMP 1U
|
||||
|
||||
//INT PRS flag
|
||||
#define HP303B__REG_INFO_INT_FLAG_PRS HP303B__REG_ADR_INT_FLAG_PRS, \
|
||||
HP303B__REG_MASK_INT_FLAG_PRS, \
|
||||
HP303B__REG_SHIFT_INT_FLAG_PRS
|
||||
#define HP303B__REG_ADR_INT_FLAG_PRS 0x0AU
|
||||
#define HP303B__REG_MASK_INT_FLAG_PRS 0x01U
|
||||
#define HP303B__REG_SHIFT_INT_FLAG_PRS 0U
|
||||
|
||||
|
||||
|
||||
#endif /* DPS310_CONSTS_H_ */
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "LibTeleinfo",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"keywords": "teleinfo, french, meter, power, erdf, linky, tic",
|
||||
"description": "Decoder for Teleinfo (aka TIC) from French smart power meters",
|
||||
"repository":
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name=LibTeleinfo
|
||||
version=1.1.1
|
||||
version=1.1.2
|
||||
author=Charles-Henri Hallard <hallard.me>
|
||||
maintainer=Charles-Henri Hallard <community.hallard.me>
|
||||
sentence=Decoder for Teleinfo (aka TIC) from French smart power meters
|
||||
|
|
|
@ -426,7 +426,45 @@ char * TInfo::valueGet(char * name, char * value)
|
|||
if (me->value) {
|
||||
// copy to dest buffer
|
||||
uint8_t lgvalue = strlen(me->value);
|
||||
strlcpy(value, me->value , lgvalue );
|
||||
strlcpy(value, me->value , lgvalue + 1 );
|
||||
return ( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// not found
|
||||
return ( NULL);
|
||||
}
|
||||
|
||||
/* ======================================================================
|
||||
Function: valueGet_P
|
||||
Purpose : get value of one element
|
||||
Input : Pointer to the label name
|
||||
pointer to the value where we fill data
|
||||
Output : pointer to the value where we filled data NULL is not found
|
||||
====================================================================== */
|
||||
char * TInfo::valueGet_P(const char * name, char * value)
|
||||
{
|
||||
// Get our linked list
|
||||
ValueList * me = &_valueslist;
|
||||
uint8_t lgname = strlen_P(name);
|
||||
|
||||
// Got one and all seems good ?
|
||||
if (me && lgname) {
|
||||
|
||||
// Loop thru the node
|
||||
while (me->next) {
|
||||
|
||||
// go to next node
|
||||
me = me->next;
|
||||
|
||||
// Check if we match this LABEL
|
||||
if (lgname==strlen(me->name) && strncmp_P(me->name, name, lgname)==0) {
|
||||
// this one has a value ?
|
||||
if (me->value) {
|
||||
// copy to dest buffer
|
||||
uint8_t lgvalue = strlen(me->value);
|
||||
strlcpy(value, me->value , lgvalue + 1 );
|
||||
return ( value );
|
||||
}
|
||||
}
|
||||
|
@ -661,7 +699,7 @@ ValueList * TInfo::checkLine(char * pline)
|
|||
return NULL;
|
||||
|
||||
// Get our own working copy
|
||||
strlcpy( buff, _recv_buff, len+1);
|
||||
strlcpy( buff, pline, len+1);
|
||||
|
||||
p = &buff[0];
|
||||
ptok = p; // for sure we start with token name
|
||||
|
|
|
@ -117,6 +117,7 @@ class TInfo
|
|||
ValueList * getList(void);
|
||||
uint8_t valuesDump(void);
|
||||
char * valueGet(char * name, char * value);
|
||||
char * valueGet_P(const char * name, char * value);
|
||||
boolean listDelete();
|
||||
unsigned char calcChecksum(char *etiquette, char *valeur) ;
|
||||
|
||||
|
|
|
@ -398,7 +398,7 @@ typedef struct __callback_assignment
|
|||
} callback_assignment_t;
|
||||
|
||||
// FastPrecisePowf from tasmota/support_float.ino
|
||||
extern float FastPrecisePowf(const float x, const float y);
|
||||
//extern float FastPrecisePowf(const float x, const float y);
|
||||
|
||||
class ESPKNXIP {
|
||||
public:
|
||||
|
@ -567,7 +567,7 @@ class ESPKNXIP {
|
|||
callback_assignment_id_t __callback_register_assignment(address_t address, callback_id_t id);
|
||||
void __callback_delete_assignment(callback_assignment_id_t id);
|
||||
|
||||
static inline float pow(float a, float b) { return FastPrecisePowf(a, b); }
|
||||
//static inline float pow(float a, float b) { return FastPrecisePowf(a, b); }
|
||||
|
||||
ESP8266WebServer *server;
|
||||
address_t physaddr;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Stripped down library for aes-ccm-decryption in the MI_NRF24.ino.
|
|
@ -0,0 +1,297 @@
|
|||
/**
|
||||
* \file aes.h
|
||||
*
|
||||
* \brief AES block cipher
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
#ifndef MBEDTLS_AES_H
|
||||
#define MBEDTLS_AES_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* padlock.c and aesni.c rely on these values! */
|
||||
#define MBEDTLS_AES_ENCRYPT 1
|
||||
#define MBEDTLS_AES_DECRYPT 0
|
||||
|
||||
#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||
#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||
|
||||
#if !defined(MBEDTLS_AES_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief AES context structure
|
||||
*
|
||||
* \note buf is able to hold 32 extra bytes, which can be used:
|
||||
* - for alignment purposes if VIA padlock is used, and/or
|
||||
* - to simplify key expansion in the 256-bit case by
|
||||
* generating an extra round key
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int nr; /*!< number of rounds */
|
||||
uint32_t *rk; /*!< AES round keys */
|
||||
uint32_t buf[68]; /*!< unaligned data */
|
||||
}
|
||||
mbedtls_aes_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize AES context
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
*/
|
||||
void mbedtls_aes_init( mbedtls_aes_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear AES context
|
||||
*
|
||||
* \param ctx AES context to be cleared
|
||||
*/
|
||||
void mbedtls_aes_free( mbedtls_aes_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief AES key schedule (encryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key encryption key
|
||||
* \param keybits must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
|
||||
/**
|
||||
* \brief AES key schedule (decryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key decryption key
|
||||
* \param keybits must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
|
||||
/**
|
||||
* \brief AES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
||||
* \param input 16-byte input block
|
||||
* \param output 16-byte output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief AES-CBC buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
/**
|
||||
* \brief AES-CFB128 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv_off offset in IV (updated after use)
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief AES-CFB8 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||
/**
|
||||
* \brief AES-CTR buffer encryption/decryption
|
||||
*
|
||||
* Warning: You have to keep the maximum use of your counter in mind!
|
||||
*
|
||||
* Note: Due to the nature of CTR you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param length The length of the data
|
||||
* \param nc_off The offset in the current stream_block (for resuming
|
||||
* within current cipher stream). The offset pointer to
|
||||
* should be 0 at the start of a stream.
|
||||
* \param nonce_counter The 128-bit nonce and counter.
|
||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
||||
* by the function.
|
||||
* \param input The input data stream
|
||||
* \param output The output data stream
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||
|
||||
/**
|
||||
* \brief Internal AES block encryption function
|
||||
* (Only exposed to allow overriding it,
|
||||
* see MBEDTLS_AES_ENCRYPT_ALT)
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param input Plaintext block
|
||||
* \param output Output (ciphertext) block
|
||||
*/
|
||||
void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Internal AES block decryption function
|
||||
* (Only exposed to allow overriding it,
|
||||
* see MBEDTLS_AES_DECRYPT_ALT)
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param input Ciphertext block
|
||||
* \param output Output (plaintext) block
|
||||
*/
|
||||
void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* MBEDTLS_AES_ALT */
|
||||
#include "aes_alt.h"
|
||||
#endif /* MBEDTLS_AES_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int mbedtls_aes_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* aes.h */
|
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
* \file ccm.h
|
||||
*
|
||||
* \brief Counter with CBC-MAC (CCM) for 128-bit block ciphers
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
#ifndef MBEDTLS_CCM_H
|
||||
#define MBEDTLS_CCM_H
|
||||
|
||||
#include "cipher.h"
|
||||
|
||||
#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to function. */
|
||||
#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief CCM context structure
|
||||
*/
|
||||
typedef struct {
|
||||
mbedtls_cipher_context_t cipher_ctx; /*!< cipher context used */
|
||||
}
|
||||
mbedtls_ccm_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize CCM context (just makes references valid)
|
||||
* Makes the context ready for mbedtls_ccm_setkey() or
|
||||
* mbedtls_ccm_free().
|
||||
*
|
||||
* \param ctx CCM context to initialize
|
||||
*/
|
||||
void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief CCM initialization (encryption and decryption)
|
||||
*
|
||||
* \param ctx CCM context to be initialized
|
||||
* \param cipher cipher to use (a 128-bit block cipher)
|
||||
* \param key encryption key
|
||||
* \param keybits key size in bits (must be acceptable by the cipher)
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
|
||||
mbedtls_cipher_id_t cipher,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
|
||||
/**
|
||||
* \brief Free a CCM context and underlying cipher sub-context
|
||||
*
|
||||
* \param ctx CCM context to free
|
||||
*/
|
||||
void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief CCM buffer encryption
|
||||
*
|
||||
* \param ctx CCM context
|
||||
* \param length length of the input data in bytes
|
||||
* \param iv nonce (initialization vector)
|
||||
* \param iv_len length of IV in bytes
|
||||
* must be 2, 3, 4, 5, 6, 7 or 8
|
||||
* \param add additional data
|
||||
* \param add_len length of additional data in bytes
|
||||
* must be less than 2^16 - 2^8
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer for holding the output data
|
||||
* must be at least 'length' bytes wide
|
||||
* \param tag buffer for holding the tag
|
||||
* \param tag_len length of the tag to generate in bytes
|
||||
* must be 4, 6, 8, 10, 14 or 16
|
||||
*
|
||||
* \note The tag is written to a separate buffer. To get the tag
|
||||
* concatenated with the output as in the CCM spec, use
|
||||
* tag = output + length and make sure the output buffer is
|
||||
* at least length + tag_len wide.
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *add, size_t add_len,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
unsigned char *tag, size_t tag_len );
|
||||
|
||||
/**
|
||||
* \brief CCM buffer authenticated decryption
|
||||
*
|
||||
* \param ctx CCM context
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector
|
||||
* \param iv_len length of IV
|
||||
* \param add additional data
|
||||
* \param add_len length of additional data
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer for holding the output data
|
||||
* \param tag buffer holding the tag
|
||||
* \param tag_len length of the tag
|
||||
*
|
||||
* \return 0 if successful and authenticated,
|
||||
* MBEDTLS_ERR_CCM_AUTH_FAILED if tag does not match
|
||||
*/
|
||||
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *add, size_t add_len,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
const unsigned char *tag, size_t tag_len );
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int mbedtls_ccm_self_test( int verbose );
|
||||
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CCM_H */
|
|
@ -0,0 +1,628 @@
|
|||
/**
|
||||
* \file check_config.h
|
||||
*
|
||||
* \brief Consistency checks for configuration options
|
||||
*
|
||||
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
/*
|
||||
* It is recommended to include this file from your config.h
|
||||
* in order to catch dependency issues early.
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CHECK_CONFIG_H
|
||||
#define MBEDTLS_CHECK_CONFIG_H
|
||||
|
||||
/*
|
||||
* We assume CHAR_BIT is 8 in many places. In practice, this is true on our
|
||||
* target platforms, so not an issue, but let's just be extra sure.
|
||||
*/
|
||||
#include <limits.h>
|
||||
#if CHAR_BIT != 8
|
||||
#error "mbed TLS requires a platform with 8-bit chars"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if !defined(MBEDTLS_PLATFORM_C)
|
||||
#error "MBEDTLS_PLATFORM_C is required on Windows"
|
||||
#endif
|
||||
|
||||
/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
|
||||
* it would confuse config.pl. */
|
||||
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
|
||||
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
|
||||
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#if defined(TARGET_LIKE_MBED) && \
|
||||
( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) )
|
||||
#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_DEPRECATED_WARNING) && \
|
||||
!defined(__GNUC__) && !defined(__clang__)
|
||||
#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME)
|
||||
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM)
|
||||
#error "MBEDTLS_AESNI_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
|
||||
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C)
|
||||
#error "MBEDTLS_DHM_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CMAC_C) && \
|
||||
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C)
|
||||
#error "MBEDTLS_CMAC_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
|
||||
#error "MBEDTLS_ECDH_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C) && \
|
||||
( !defined(MBEDTLS_ECP_C) || \
|
||||
!defined(MBEDTLS_ASN1_PARSE_C) || \
|
||||
!defined(MBEDTLS_ASN1_WRITE_C) )
|
||||
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECJPAKE_C) && \
|
||||
( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) )
|
||||
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
|
||||
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
|
||||
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
|
||||
!defined(MBEDTLS_SHA256_C))
|
||||
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
|
||||
#endif
|
||||
#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \
|
||||
defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64)
|
||||
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
|
||||
#endif
|
||||
#if defined(MBEDTLS_ENTROPY_C) && \
|
||||
( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \
|
||||
&& defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32)
|
||||
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
|
||||
#endif
|
||||
#if defined(MBEDTLS_ENTROPY_C) && \
|
||||
defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C)
|
||||
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
|
||||
( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
|
||||
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
|
||||
#endif
|
||||
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
|
||||
( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \
|
||||
defined(MBEDTLS_HAVEGE_C) )
|
||||
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_GCM_C) && ( \
|
||||
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
|
||||
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C)
|
||||
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C)
|
||||
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
|
||||
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
|
||||
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C)
|
||||
#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
|
||||
!defined(MBEDTLS_ECDH_C)
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
|
||||
( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \
|
||||
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
|
||||
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
|
||||
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
|
||||
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
|
||||
!defined(MBEDTLS_X509_CRT_PARSE_C) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
|
||||
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
|
||||
!defined(MBEDTLS_PKCS1_V15) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
|
||||
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
|
||||
!defined(MBEDTLS_PKCS1_V15) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
|
||||
( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \
|
||||
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
|
||||
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
|
||||
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
|
||||
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C)
|
||||
#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C)
|
||||
#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_C) && \
|
||||
( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) )
|
||||
#error "MBEDTLS_PK_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C)
|
||||
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C)
|
||||
#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C)
|
||||
#error "MBEDTLS_PKCS11_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C)
|
||||
#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C)
|
||||
#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\
|
||||
( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\
|
||||
defined(MBEDTLS_PLATFORM_EXIT_ALT) )
|
||||
#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\
|
||||
( !defined(MBEDTLS_PLATFORM_C) ||\
|
||||
!defined(MBEDTLS_HAVE_TIME) )
|
||||
#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\
|
||||
( !defined(MBEDTLS_PLATFORM_C) ||\
|
||||
!defined(MBEDTLS_HAVE_TIME) )
|
||||
#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
|
||||
( !defined(MBEDTLS_PLATFORM_C) ||\
|
||||
!defined(MBEDTLS_HAVE_TIME) )
|
||||
#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\
|
||||
( defined(MBEDTLS_PLATFORM_STD_TIME) ||\
|
||||
defined(MBEDTLS_PLATFORM_TIME_ALT) )
|
||||
#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
|
||||
( defined(MBEDTLS_PLATFORM_STD_TIME) ||\
|
||||
defined(MBEDTLS_PLATFORM_TIME_ALT) )
|
||||
#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
|
||||
#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
|
||||
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\
|
||||
( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\
|
||||
defined(MBEDTLS_PLATFORM_FPRINTF_ALT) )
|
||||
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
|
||||
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
|
||||
#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
|
||||
defined(MBEDTLS_PLATFORM_STD_FREE)
|
||||
#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
|
||||
#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
|
||||
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
|
||||
#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
|
||||
defined(MBEDTLS_PLATFORM_STD_CALLOC)
|
||||
#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO)
|
||||
#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C)
|
||||
#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
|
||||
#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
|
||||
#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\
|
||||
( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\
|
||||
defined(MBEDTLS_PLATFORM_PRINTF_ALT) )
|
||||
#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
|
||||
#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
|
||||
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\
|
||||
( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\
|
||||
defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) )
|
||||
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\
|
||||
!defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
|
||||
#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
|
||||
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
|
||||
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY)
|
||||
#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\
|
||||
!defined(MBEDTLS_PLATFORM_EXIT_ALT)
|
||||
#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\
|
||||
( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\
|
||||
!defined(MBEDTLS_HAVE_TIME) )
|
||||
#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\
|
||||
!defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
|
||||
#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\
|
||||
!defined(MBEDTLS_PLATFORM_PRINTF_ALT)
|
||||
#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\
|
||||
!defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
|
||||
#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\
|
||||
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) )
|
||||
#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\
|
||||
!defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\
|
||||
!defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
|
||||
#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\
|
||||
!defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
|
||||
#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\
|
||||
( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\
|
||||
defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
|
||||
#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\
|
||||
( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\
|
||||
defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
|
||||
#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
|
||||
!defined(MBEDTLS_OID_C) )
|
||||
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \
|
||||
!defined(MBEDTLS_PKCS1_V15) )
|
||||
#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
|
||||
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) )
|
||||
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \
|
||||
!defined(MBEDTLS_SHA1_C) )
|
||||
#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \
|
||||
!defined(MBEDTLS_SHA1_C) )
|
||||
#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \
|
||||
!defined(MBEDTLS_SHA1_C) )
|
||||
#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \
|
||||
!defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) )
|
||||
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C)
|
||||
#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \
|
||||
!defined(MBEDTLS_MD_C) )
|
||||
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C)
|
||||
#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_2))
|
||||
#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1))
|
||||
#error "Illegal protocol selection"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1))
|
||||
#error "Illegal protocol selection"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_1)))
|
||||
#error "Illegal protocol selection"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||
#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \
|
||||
!defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
|
||||
#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \
|
||||
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
|
||||
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \
|
||||
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
|
||||
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
|
||||
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1)
|
||||
#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
|
||||
!defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_PTHREAD)
|
||||
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
|
||||
#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites"
|
||||
#endif
|
||||
#define MBEDTLS_THREADING_IMPL
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_ALT)
|
||||
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
|
||||
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
|
||||
#endif
|
||||
#define MBEDTLS_THREADING_IMPL
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL)
|
||||
#error "MBEDTLS_THREADING_C defined, single threading implementation required"
|
||||
#endif
|
||||
#undef MBEDTLS_THREADING_IMPL
|
||||
|
||||
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
|
||||
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
|
||||
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \
|
||||
!defined(MBEDTLS_PK_PARSE_C) )
|
||||
#error "MBEDTLS_X509_USE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
|
||||
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \
|
||||
!defined(MBEDTLS_PK_WRITE_C) )
|
||||
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
|
||||
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
|
||||
#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
|
||||
#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
|
||||
#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
|
||||
#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Avoid warning from -pedantic. This is a convenient place for this
|
||||
* workaround since this is included by every single file before the
|
||||
* #if defined(MBEDTLS_xxx_C) that results in emtpy translation units.
|
||||
*/
|
||||
typedef int mbedtls_iso_c_forbids_empty_translation_units;
|
||||
|
||||
#endif /* MBEDTLS_CHECK_CONFIG_H */
|
|
@ -0,0 +1,709 @@
|
|||
/**
|
||||
* \file cipher.h
|
||||
*
|
||||
* \brief Generic cipher wrapper.
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CIPHER_H
|
||||
#define MBEDTLS_CIPHER_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)
|
||||
#define MBEDTLS_CIPHER_MODE_AEAD
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
#define MBEDTLS_CIPHER_MODE_WITH_PADDING
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ARC4_C)
|
||||
#define MBEDTLS_CIPHER_MODE_STREAM
|
||||
#endif
|
||||
|
||||
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
||||
!defined(inline) && !defined(__cplusplus)
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */
|
||||
#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters to function. */
|
||||
#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */
|
||||
#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */
|
||||
#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
|
||||
#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */
|
||||
#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid, eg because it was free()ed. */
|
||||
|
||||
#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length */
|
||||
#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_CIPHER_ID_NONE = 0,
|
||||
MBEDTLS_CIPHER_ID_NULL,
|
||||
MBEDTLS_CIPHER_ID_AES,
|
||||
MBEDTLS_CIPHER_ID_DES,
|
||||
MBEDTLS_CIPHER_ID_3DES,
|
||||
MBEDTLS_CIPHER_ID_CAMELLIA,
|
||||
MBEDTLS_CIPHER_ID_BLOWFISH,
|
||||
MBEDTLS_CIPHER_ID_ARC4,
|
||||
} mbedtls_cipher_id_t;
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_CIPHER_NONE = 0,
|
||||
MBEDTLS_CIPHER_NULL,
|
||||
MBEDTLS_CIPHER_AES_128_ECB,
|
||||
MBEDTLS_CIPHER_AES_192_ECB,
|
||||
MBEDTLS_CIPHER_AES_256_ECB,
|
||||
MBEDTLS_CIPHER_AES_128_CBC,
|
||||
MBEDTLS_CIPHER_AES_192_CBC,
|
||||
MBEDTLS_CIPHER_AES_256_CBC,
|
||||
MBEDTLS_CIPHER_AES_128_CFB128,
|
||||
MBEDTLS_CIPHER_AES_192_CFB128,
|
||||
MBEDTLS_CIPHER_AES_256_CFB128,
|
||||
MBEDTLS_CIPHER_AES_128_CTR,
|
||||
MBEDTLS_CIPHER_AES_192_CTR,
|
||||
MBEDTLS_CIPHER_AES_256_CTR,
|
||||
MBEDTLS_CIPHER_AES_128_GCM,
|
||||
MBEDTLS_CIPHER_AES_192_GCM,
|
||||
MBEDTLS_CIPHER_AES_256_GCM,
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_ECB,
|
||||
MBEDTLS_CIPHER_CAMELLIA_192_ECB,
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_ECB,
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_CBC,
|
||||
MBEDTLS_CIPHER_CAMELLIA_192_CBC,
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_CBC,
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_CFB128,
|
||||
MBEDTLS_CIPHER_CAMELLIA_192_CFB128,
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_CFB128,
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_CTR,
|
||||
MBEDTLS_CIPHER_CAMELLIA_192_CTR,
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_CTR,
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_GCM,
|
||||
MBEDTLS_CIPHER_CAMELLIA_192_GCM,
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_GCM,
|
||||
MBEDTLS_CIPHER_DES_ECB,
|
||||
MBEDTLS_CIPHER_DES_CBC,
|
||||
MBEDTLS_CIPHER_DES_EDE_ECB,
|
||||
MBEDTLS_CIPHER_DES_EDE_CBC,
|
||||
MBEDTLS_CIPHER_DES_EDE3_ECB,
|
||||
MBEDTLS_CIPHER_DES_EDE3_CBC,
|
||||
MBEDTLS_CIPHER_BLOWFISH_ECB,
|
||||
MBEDTLS_CIPHER_BLOWFISH_CBC,
|
||||
MBEDTLS_CIPHER_BLOWFISH_CFB64,
|
||||
MBEDTLS_CIPHER_BLOWFISH_CTR,
|
||||
MBEDTLS_CIPHER_ARC4_128,
|
||||
MBEDTLS_CIPHER_AES_128_CCM,
|
||||
MBEDTLS_CIPHER_AES_192_CCM,
|
||||
MBEDTLS_CIPHER_AES_256_CCM,
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_CCM,
|
||||
MBEDTLS_CIPHER_CAMELLIA_192_CCM,
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_CCM,
|
||||
} mbedtls_cipher_type_t;
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_MODE_NONE = 0,
|
||||
MBEDTLS_MODE_ECB,
|
||||
MBEDTLS_MODE_CBC,
|
||||
MBEDTLS_MODE_CFB,
|
||||
MBEDTLS_MODE_OFB, /* Unused! */
|
||||
MBEDTLS_MODE_CTR,
|
||||
MBEDTLS_MODE_GCM,
|
||||
MBEDTLS_MODE_STREAM,
|
||||
MBEDTLS_MODE_CCM,
|
||||
} mbedtls_cipher_mode_t;
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default) */
|
||||
MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding */
|
||||
MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding */
|
||||
MBEDTLS_PADDING_ZEROS, /**< zero padding (not reversible!) */
|
||||
MBEDTLS_PADDING_NONE, /**< never pad (full blocks only) */
|
||||
} mbedtls_cipher_padding_t;
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_OPERATION_NONE = -1,
|
||||
MBEDTLS_DECRYPT = 0,
|
||||
MBEDTLS_ENCRYPT,
|
||||
} mbedtls_operation_t;
|
||||
|
||||
enum {
|
||||
/** Undefined key length */
|
||||
MBEDTLS_KEY_LENGTH_NONE = 0,
|
||||
/** Key length, in bits (including parity), for DES keys */
|
||||
MBEDTLS_KEY_LENGTH_DES = 64,
|
||||
/** Key length, in bits (including parity), for DES in two key EDE */
|
||||
MBEDTLS_KEY_LENGTH_DES_EDE = 128,
|
||||
/** Key length, in bits (including parity), for DES in three-key EDE */
|
||||
MBEDTLS_KEY_LENGTH_DES_EDE3 = 192,
|
||||
};
|
||||
|
||||
/** Maximum length of any IV, in bytes */
|
||||
#define MBEDTLS_MAX_IV_LENGTH 16
|
||||
/** Maximum block size of any cipher, in bytes */
|
||||
#define MBEDTLS_MAX_BLOCK_LENGTH 16
|
||||
|
||||
/**
|
||||
* Base cipher information (opaque struct).
|
||||
*/
|
||||
typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t;
|
||||
|
||||
/**
|
||||
* CMAC context (opaque struct).
|
||||
*/
|
||||
typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
|
||||
|
||||
/**
|
||||
* Cipher information. Allows cipher functions to be called in a generic way.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Full cipher identifier (e.g. MBEDTLS_CIPHER_AES_256_CBC) */
|
||||
mbedtls_cipher_type_t type;
|
||||
|
||||
/** Cipher mode (e.g. MBEDTLS_MODE_CBC) */
|
||||
mbedtls_cipher_mode_t mode;
|
||||
|
||||
/** Cipher key length, in bits (default length for variable sized ciphers)
|
||||
* (Includes parity bits for ciphers like DES) */
|
||||
unsigned int key_bitlen;
|
||||
|
||||
/** Name of the cipher */
|
||||
const char * name;
|
||||
|
||||
/** IV/NONCE size, in bytes.
|
||||
* For cipher that accept many sizes: recommended size */
|
||||
unsigned int iv_size;
|
||||
|
||||
/** Flags for variable IV size, variable key size, etc. */
|
||||
int flags;
|
||||
|
||||
/** block size, in bytes */
|
||||
unsigned int block_size;
|
||||
|
||||
/** Base cipher information and functions */
|
||||
const mbedtls_cipher_base_t *base;
|
||||
|
||||
} mbedtls_cipher_info_t;
|
||||
|
||||
/**
|
||||
* Generic cipher context.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Information about the associated cipher */
|
||||
const mbedtls_cipher_info_t *cipher_info;
|
||||
|
||||
/** Key length to use */
|
||||
int key_bitlen;
|
||||
|
||||
/** Operation that the context's key has been initialised for */
|
||||
mbedtls_operation_t operation;
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
|
||||
/** Padding functions to use, if relevant for cipher mode */
|
||||
void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
|
||||
int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
|
||||
#endif
|
||||
|
||||
/** Buffer for data that hasn't been encrypted yet */
|
||||
unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
|
||||
|
||||
/** Number of bytes that still need processing */
|
||||
size_t unprocessed_len;
|
||||
|
||||
/** Current IV or NONCE_COUNTER for CTR-mode */
|
||||
unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
|
||||
|
||||
/** IV size in bytes (for ciphers with variable-length IVs) */
|
||||
size_t iv_size;
|
||||
|
||||
/** Cipher-specific context */
|
||||
void *cipher_ctx;
|
||||
|
||||
#if defined(MBEDTLS_CMAC_C)
|
||||
/** CMAC Specific context */
|
||||
mbedtls_cmac_context_t *cmac_ctx;
|
||||
#endif
|
||||
} mbedtls_cipher_context_t;
|
||||
|
||||
/**
|
||||
* \brief Returns the list of ciphers supported by the generic cipher module.
|
||||
*
|
||||
* \return a statically allocated array of ciphers, the last entry
|
||||
* is 0.
|
||||
*/
|
||||
const int *mbedtls_cipher_list( void );
|
||||
|
||||
/**
|
||||
* \brief Returns the cipher information structure associated
|
||||
* with the given cipher name.
|
||||
*
|
||||
* \param cipher_name Name of the cipher to search for.
|
||||
*
|
||||
* \return the cipher information structure associated with the
|
||||
* given cipher_name, or NULL if not found.
|
||||
*/
|
||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
|
||||
|
||||
/**
|
||||
* \brief Returns the cipher information structure associated
|
||||
* with the given cipher type.
|
||||
*
|
||||
* \param cipher_type Type of the cipher to search for.
|
||||
*
|
||||
* \return the cipher information structure associated with the
|
||||
* given cipher_type, or NULL if not found.
|
||||
*/
|
||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
|
||||
|
||||
/**
|
||||
* \brief Returns the cipher information structure associated
|
||||
* with the given cipher id, key size and mode.
|
||||
*
|
||||
* \param cipher_id Id of the cipher to search for
|
||||
* (e.g. MBEDTLS_CIPHER_ID_AES)
|
||||
* \param key_bitlen Length of the key in bits
|
||||
* \param mode Cipher mode (e.g. MBEDTLS_MODE_CBC)
|
||||
*
|
||||
* \return the cipher information structure associated with the
|
||||
* given cipher_type, or NULL if not found.
|
||||
*/
|
||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
|
||||
int key_bitlen,
|
||||
const mbedtls_cipher_mode_t mode );
|
||||
|
||||
/**
|
||||
* \brief Initialize a cipher_context (as NONE)
|
||||
*/
|
||||
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
|
||||
|
||||
/**
|
||||
* \brief Free and clear the cipher-specific context of ctx.
|
||||
* Freeing ctx itself remains the responsibility of the
|
||||
* caller.
|
||||
*/
|
||||
void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
|
||||
|
||||
/**
|
||||
* \brief Initialises and fills the cipher context structure with
|
||||
* the appropriate values.
|
||||
*
|
||||
* \note Currently also clears structure. In future versions you
|
||||
* will be required to call mbedtls_cipher_init() on the structure
|
||||
* first.
|
||||
*
|
||||
* \param ctx context to initialise. May not be NULL.
|
||||
* \param cipher_info cipher to use.
|
||||
*
|
||||
* \return 0 on success,
|
||||
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure,
|
||||
* MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
|
||||
* cipher-specific context failed.
|
||||
*/
|
||||
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info );
|
||||
|
||||
/**
|
||||
* \brief Returns the block size of the given cipher.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return size of the cipher's blocks, or 0 if ctx has not been
|
||||
* initialised.
|
||||
*/
|
||||
static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return 0;
|
||||
|
||||
return ctx->cipher_info->block_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the mode of operation for the cipher.
|
||||
* (e.g. MBEDTLS_MODE_CBC)
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return mode of operation, or MBEDTLS_MODE_NONE if ctx
|
||||
* has not been initialised.
|
||||
*/
|
||||
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return MBEDTLS_MODE_NONE;
|
||||
|
||||
return ctx->cipher_info->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the size of the cipher's IV/NONCE in bytes.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return If IV has not been set yet: (recommended) IV size
|
||||
* (0 for ciphers not using IV/NONCE).
|
||||
* If IV has already been set: actual size.
|
||||
*/
|
||||
static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return 0;
|
||||
|
||||
if( ctx->iv_size != 0 )
|
||||
return (int) ctx->iv_size;
|
||||
|
||||
return (int) ctx->cipher_info->iv_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the type of the given cipher.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return type of the cipher, or MBEDTLS_CIPHER_NONE if ctx has
|
||||
* not been initialised.
|
||||
*/
|
||||
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return MBEDTLS_CIPHER_NONE;
|
||||
|
||||
return ctx->cipher_info->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the name of the given cipher, as a string.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return name of the cipher, or NULL if ctx was not initialised.
|
||||
*/
|
||||
static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return 0;
|
||||
|
||||
return ctx->cipher_info->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the key length of the cipher.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return cipher's key length, in bits, or
|
||||
* MBEDTLS_KEY_LENGTH_NONE if ctx has not been
|
||||
* initialised.
|
||||
*/
|
||||
static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return MBEDTLS_KEY_LENGTH_NONE;
|
||||
|
||||
return (int) ctx->cipher_info->key_bitlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the operation of the given cipher.
|
||||
*
|
||||
* \param ctx cipher's context. Must have been initialised.
|
||||
*
|
||||
* \return operation (MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT),
|
||||
* or MBEDTLS_OPERATION_NONE if ctx has not been
|
||||
* initialised.
|
||||
*/
|
||||
static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return MBEDTLS_OPERATION_NONE;
|
||||
|
||||
return ctx->operation;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the key to use with the given context.
|
||||
*
|
||||
* \param ctx generic cipher context. May not be NULL. Must have been
|
||||
* initialised using cipher_context_from_type or
|
||||
* cipher_context_from_string.
|
||||
* \param key The key to use.
|
||||
* \param key_bitlen key length to use, in bits.
|
||||
* \param operation Operation that the key will be used for, either
|
||||
* MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT.
|
||||
*
|
||||
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
|
||||
* parameter verification fails or a cipher specific
|
||||
* error code.
|
||||
*/
|
||||
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
|
||||
int key_bitlen, const mbedtls_operation_t operation );
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
|
||||
/**
|
||||
* \brief Set padding mode, for cipher modes that use padding.
|
||||
* (Default: PKCS7 padding.)
|
||||
*
|
||||
* \param ctx generic cipher context
|
||||
* \param mode padding mode
|
||||
*
|
||||
* \returns 0 on success, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
|
||||
* if selected padding mode is not supported, or
|
||||
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
|
||||
* does not support padding.
|
||||
*/
|
||||
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode );
|
||||
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
|
||||
|
||||
/**
|
||||
* \brief Set the initialization vector (IV) or nonce
|
||||
*
|
||||
* \param ctx generic cipher context
|
||||
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers)
|
||||
* \param iv_len IV length for ciphers with variable-size IV;
|
||||
* discarded by ciphers with fixed-size IV.
|
||||
*
|
||||
* \returns 0 on success, or MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
|
||||
*
|
||||
* \note Some ciphers don't use IVs nor NONCE. For these
|
||||
* ciphers, this function has no effect.
|
||||
*/
|
||||
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *iv, size_t iv_len );
|
||||
|
||||
/**
|
||||
* \brief Finish preparation of the given context
|
||||
*
|
||||
* \param ctx generic cipher context
|
||||
*
|
||||
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
|
||||
* if parameter verification fails.
|
||||
*/
|
||||
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
/**
|
||||
* \brief Add additional data (for AEAD ciphers).
|
||||
* Currently only supported with GCM.
|
||||
* Must be called exactly once, after mbedtls_cipher_reset().
|
||||
*
|
||||
* \param ctx generic cipher context
|
||||
* \param ad Additional data to use.
|
||||
* \param ad_len Length of ad.
|
||||
*
|
||||
* \return 0 on success, or a specific error code.
|
||||
*/
|
||||
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *ad, size_t ad_len );
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
|
||||
/**
|
||||
* \brief Generic cipher update function. Encrypts/decrypts
|
||||
* using the given cipher context. Writes as many block
|
||||
* size'd blocks of data as possible to output. Any data
|
||||
* that cannot be written immediately will either be added
|
||||
* to the next block, or flushed when cipher_final is
|
||||
* called.
|
||||
* Exception: for MBEDTLS_MODE_ECB, expects single block
|
||||
* in size (e.g. 16 bytes for AES)
|
||||
*
|
||||
* \param ctx generic cipher context
|
||||
* \param input buffer holding the input data
|
||||
* \param ilen length of the input data
|
||||
* \param output buffer for the output data. Should be able to hold at
|
||||
* least ilen + block_size. Cannot be the same buffer as
|
||||
* input!
|
||||
* \param olen length of the output data, will be filled with the
|
||||
* actual number of bytes written.
|
||||
*
|
||||
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
|
||||
* parameter verification fails,
|
||||
* MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
|
||||
* unsupported mode for a cipher or a cipher specific
|
||||
* error code.
|
||||
*
|
||||
* \note If the underlying cipher is GCM, all calls to this
|
||||
* function, except the last one before mbedtls_cipher_finish(),
|
||||
* must have ilen a multiple of the block size.
|
||||
*/
|
||||
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
|
||||
size_t ilen, unsigned char *output, size_t *olen );
|
||||
|
||||
/**
|
||||
* \brief Generic cipher finalisation function. If data still
|
||||
* needs to be flushed from an incomplete block, data
|
||||
* contained within it will be padded with the size of
|
||||
* the last block, and written to the output buffer.
|
||||
*
|
||||
* \param ctx Generic cipher context
|
||||
* \param output buffer to write data to. Needs block_size available.
|
||||
* \param olen length of the data written to the output buffer.
|
||||
*
|
||||
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
|
||||
* parameter verification fails,
|
||||
* MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
|
||||
* expected a full block but was not provided one,
|
||||
* MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
|
||||
* while decrypting or a cipher specific error code.
|
||||
*/
|
||||
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
|
||||
unsigned char *output, size_t *olen );
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
/**
|
||||
* \brief Write tag for AEAD ciphers.
|
||||
* Currently only supported with GCM.
|
||||
* Must be called after mbedtls_cipher_finish().
|
||||
*
|
||||
* \param ctx Generic cipher context
|
||||
* \param tag buffer to write the tag
|
||||
* \param tag_len Length of the tag to write
|
||||
*
|
||||
* \return 0 on success, or a specific error code.
|
||||
*/
|
||||
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
|
||||
unsigned char *tag, size_t tag_len );
|
||||
|
||||
/**
|
||||
* \brief Check tag for AEAD ciphers.
|
||||
* Currently only supported with GCM.
|
||||
* Must be called after mbedtls_cipher_finish().
|
||||
*
|
||||
* \param ctx Generic cipher context
|
||||
* \param tag Buffer holding the tag
|
||||
* \param tag_len Length of the tag to check
|
||||
*
|
||||
* \return 0 on success, or a specific error code.
|
||||
*/
|
||||
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *tag, size_t tag_len );
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
|
||||
/**
|
||||
* \brief Generic all-in-one encryption/decryption
|
||||
* (for all ciphers except AEAD constructs).
|
||||
*
|
||||
* \param ctx generic cipher context
|
||||
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers)
|
||||
* \param iv_len IV length for ciphers with variable-size IV;
|
||||
* discarded by ciphers with fixed-size IV.
|
||||
* \param input buffer holding the input data
|
||||
* \param ilen length of the input data
|
||||
* \param output buffer for the output data. Should be able to hold at
|
||||
* least ilen + block_size. Cannot be the same buffer as
|
||||
* input!
|
||||
* \param olen length of the output data, will be filled with the
|
||||
* actual number of bytes written.
|
||||
*
|
||||
* \note Some ciphers don't use IVs nor NONCE. For these
|
||||
* ciphers, use iv = NULL and iv_len = 0.
|
||||
*
|
||||
* \returns 0 on success, or
|
||||
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
|
||||
* MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
|
||||
* expected a full block but was not provided one, or
|
||||
* MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
|
||||
* while decrypting, or
|
||||
* a cipher specific error code.
|
||||
*/
|
||||
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen );
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
|
||||
/**
|
||||
* \brief Generic autenticated encryption (AEAD ciphers).
|
||||
*
|
||||
* \param ctx generic cipher context
|
||||
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers)
|
||||
* \param iv_len IV length for ciphers with variable-size IV;
|
||||
* discarded by ciphers with fixed-size IV.
|
||||
* \param ad Additional data to authenticate.
|
||||
* \param ad_len Length of ad.
|
||||
* \param input buffer holding the input data
|
||||
* \param ilen length of the input data
|
||||
* \param output buffer for the output data.
|
||||
* Should be able to hold at least ilen.
|
||||
* \param olen length of the output data, will be filled with the
|
||||
* actual number of bytes written.
|
||||
* \param tag buffer for the authentication tag
|
||||
* \param tag_len desired tag length
|
||||
*
|
||||
* \returns 0 on success, or
|
||||
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
|
||||
* a cipher specific error code.
|
||||
*/
|
||||
int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *ad, size_t ad_len,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen,
|
||||
unsigned char *tag, size_t tag_len );
|
||||
|
||||
/**
|
||||
* \brief Generic autenticated decryption (AEAD ciphers).
|
||||
*
|
||||
* \param ctx generic cipher context
|
||||
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers)
|
||||
* \param iv_len IV length for ciphers with variable-size IV;
|
||||
* discarded by ciphers with fixed-size IV.
|
||||
* \param ad Additional data to be authenticated.
|
||||
* \param ad_len Length of ad.
|
||||
* \param input buffer holding the input data
|
||||
* \param ilen length of the input data
|
||||
* \param output buffer for the output data.
|
||||
* Should be able to hold at least ilen.
|
||||
* \param olen length of the output data, will be filled with the
|
||||
* actual number of bytes written.
|
||||
* \param tag buffer holding the authentication tag
|
||||
* \param tag_len length of the authentication tag
|
||||
*
|
||||
* \returns 0 on success, or
|
||||
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
|
||||
* MBEDTLS_ERR_CIPHER_AUTH_FAILED if data isn't authentic,
|
||||
* or a cipher specific error code.
|
||||
*
|
||||
* \note If the data is not authentic, then the output buffer
|
||||
* is zeroed out to prevent the unauthentic plaintext to
|
||||
* be used by mistake, making this interface safer.
|
||||
*/
|
||||
int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *ad, size_t ad_len,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen,
|
||||
const unsigned char *tag, size_t tag_len );
|
||||
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CIPHER_H */
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* \file cipher_internal.h
|
||||
*
|
||||
* \brief Cipher wrappers.
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
#ifndef MBEDTLS_CIPHER_WRAP_H
|
||||
#define MBEDTLS_CIPHER_WRAP_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include "cipher.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Base cipher information. The non-mode specific functions and values.
|
||||
*/
|
||||
struct mbedtls_cipher_base_t
|
||||
{
|
||||
/** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
|
||||
mbedtls_cipher_id_t cipher;
|
||||
|
||||
/** Encrypt using ECB */
|
||||
int (*ecb_func)( void *ctx, mbedtls_operation_t mode,
|
||||
const unsigned char *input, unsigned char *output );
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/** Encrypt using CBC */
|
||||
int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length,
|
||||
unsigned char *iv, const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
/** Encrypt using CFB (Full length) */
|
||||
int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
|
||||
unsigned char *iv, const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||
/** Encrypt using CTR */
|
||||
int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
|
||||
unsigned char *nonce_counter, unsigned char *stream_block,
|
||||
const unsigned char *input, unsigned char *output );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
|
||||
/** Encrypt using STREAM */
|
||||
int (*stream_func)( void *ctx, size_t length,
|
||||
const unsigned char *input, unsigned char *output );
|
||||
#endif
|
||||
|
||||
/** Set key for encryption purposes */
|
||||
int (*setkey_enc_func)( void *ctx, const unsigned char *key,
|
||||
unsigned int key_bitlen );
|
||||
|
||||
/** Set key for decryption purposes */
|
||||
int (*setkey_dec_func)( void *ctx, const unsigned char *key,
|
||||
unsigned int key_bitlen);
|
||||
|
||||
/** Allocate a new context */
|
||||
void * (*ctx_alloc_func)( void );
|
||||
|
||||
/** Free the given context */
|
||||
void (*ctx_free_func)( void *ctx );
|
||||
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mbedtls_cipher_type_t type;
|
||||
const mbedtls_cipher_info_t *info;
|
||||
} mbedtls_cipher_definition_t;
|
||||
|
||||
extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
|
||||
|
||||
extern int mbedtls_cipher_supported[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CIPHER_WRAP_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,295 @@
|
|||
/**
|
||||
* \file platform.h
|
||||
*
|
||||
* \brief mbed TLS Platform abstraction layer
|
||||
*
|
||||
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
#ifndef MBEDTLS_PLATFORM_H
|
||||
#define MBEDTLS_PLATFORM_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#include "mbedtls/platform_time.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name SECTION: Module settings
|
||||
*
|
||||
* The configuration options you can set for this module are in this section.
|
||||
* Either change them in config.h or define them on the compiler command line.
|
||||
* \{
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
|
||||
#if defined(_WIN32)
|
||||
#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< Default snprintf to use */
|
||||
#else
|
||||
#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use */
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
|
||||
#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
|
||||
#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
|
||||
#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_FREE)
|
||||
#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_TIME)
|
||||
#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< Default exit value to use */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< Default exit value to use */
|
||||
#endif
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
|
||||
#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
|
||||
#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE)
|
||||
#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile"
|
||||
#endif
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
|
||||
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
|
||||
#include MBEDTLS_PLATFORM_STD_MEM_HDR
|
||||
#endif
|
||||
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
|
||||
|
||||
|
||||
/* \} name SECTION: Module settings */
|
||||
|
||||
/*
|
||||
* The function pointers for calloc and free
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_MEMORY)
|
||||
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
|
||||
defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
|
||||
#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO
|
||||
#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO
|
||||
#else
|
||||
/* For size_t */
|
||||
#include <stddef.h>
|
||||
extern void * (*mbedtls_calloc)( size_t n, size_t size );
|
||||
extern void (*mbedtls_free)( void *ptr );
|
||||
|
||||
/**
|
||||
* \brief Set your own memory implementation function pointers
|
||||
*
|
||||
* \param calloc_func the calloc function implementation
|
||||
* \param free_func the free function implementation
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
|
||||
void (*free_func)( void * ) );
|
||||
#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
|
||||
#else /* !MBEDTLS_PLATFORM_MEMORY */
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_calloc calloc
|
||||
#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */
|
||||
|
||||
/*
|
||||
* The function pointers for fprintf
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
|
||||
/* We need FILE * */
|
||||
#include <stdio.h>
|
||||
extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... );
|
||||
|
||||
/**
|
||||
* \brief Set your own fprintf function pointer
|
||||
*
|
||||
* \param fprintf_func the fprintf function implementation
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *,
|
||||
... ) );
|
||||
#else
|
||||
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO)
|
||||
#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO
|
||||
#else
|
||||
#define mbedtls_fprintf fprintf
|
||||
#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
|
||||
|
||||
/*
|
||||
* The function pointers for printf
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
|
||||
extern int (*mbedtls_printf)( const char *format, ... );
|
||||
|
||||
/**
|
||||
* \brief Set your own printf function pointer
|
||||
*
|
||||
* \param printf_func the printf function implementation
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) );
|
||||
#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
|
||||
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO)
|
||||
#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO
|
||||
#else
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
|
||||
|
||||
/*
|
||||
* The function pointers for snprintf
|
||||
*
|
||||
* The snprintf implementation should conform to C99:
|
||||
* - it *must* always correctly zero-terminate the buffer
|
||||
* (except when n == 0, then it must leave the buffer untouched)
|
||||
* - however it is acceptable to return -1 instead of the required length when
|
||||
* the destination buffer is too short.
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
/* For Windows (inc. MSYS2), we provide our own fixed implementation */
|
||||
int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
|
||||
extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
|
||||
|
||||
/**
|
||||
* \brief Set your own snprintf function pointer
|
||||
*
|
||||
* \param snprintf_func the snprintf function implementation
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
|
||||
const char * format, ... ) );
|
||||
#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
|
||||
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
|
||||
#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO
|
||||
#else
|
||||
#define mbedtls_snprintf snprintf
|
||||
#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
|
||||
|
||||
/*
|
||||
* The function pointers for exit
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
|
||||
extern void (*mbedtls_exit)( int status );
|
||||
|
||||
/**
|
||||
* \brief Set your own exit function pointer
|
||||
*
|
||||
* \param exit_func the exit function implementation
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_platform_set_exit( void (*exit_func)( int status ) );
|
||||
#else
|
||||
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO)
|
||||
#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO
|
||||
#else
|
||||
#define mbedtls_exit exit
|
||||
#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
|
||||
|
||||
/*
|
||||
* The default exit values
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
|
||||
#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
|
||||
#else
|
||||
#define MBEDTLS_EXIT_SUCCESS 0
|
||||
#endif
|
||||
#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
|
||||
#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE
|
||||
#else
|
||||
#define MBEDTLS_EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The function pointers for reading from and writing a seed file to
|
||||
* Non-Volatile storage (NV) in a platform-independent way
|
||||
*
|
||||
* Only enabled when the NV seed entropy source is enabled
|
||||
*/
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
|
||||
/* Internal standard platform definitions */
|
||||
int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len );
|
||||
int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
|
||||
extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len );
|
||||
extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len );
|
||||
|
||||
/**
|
||||
* \brief Set your own seed file writing/reading functions
|
||||
*
|
||||
* \param nv_seed_read_func the seed reading function implementation
|
||||
* \param nv_seed_write_func the seed writing function implementation
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_platform_set_nv_seed(
|
||||
int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
|
||||
int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len )
|
||||
);
|
||||
#else
|
||||
#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
|
||||
defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
|
||||
#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
|
||||
#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO
|
||||
#else
|
||||
#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read
|
||||
#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write
|
||||
#endif
|
||||
#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
|
||||
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* platform.h */
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* \file platform_time.h
|
||||
*
|
||||
* \brief mbed TLS Platform time abstraction
|
||||
*
|
||||
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
#ifndef MBEDTLS_PLATFORM_TIME_H
|
||||
#define MBEDTLS_PLATFORM_TIME_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name SECTION: Module settings
|
||||
*
|
||||
* The configuration options you can set for this module are in this section.
|
||||
* Either change them in config.h or define them on the compiler command line.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*
|
||||
* The time_t datatype
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO)
|
||||
typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t;
|
||||
#else
|
||||
/* For time_t */
|
||||
#include <time.h>
|
||||
typedef time_t mbedtls_time_t;
|
||||
#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */
|
||||
|
||||
/*
|
||||
* The function pointers for time
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_ALT)
|
||||
extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time );
|
||||
|
||||
/**
|
||||
* \brief Set your own time function pointer
|
||||
*
|
||||
* \param time_func the time function implementation
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) );
|
||||
#else
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_MACRO)
|
||||
#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO
|
||||
#else
|
||||
#define mbedtls_time time
|
||||
#endif /* MBEDTLS_PLATFORM_TIME_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_TIME_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* platform_time.h */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,464 @@
|
|||
/*
|
||||
* NIST SP800-38C compliant CCM implementation
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Definition of CCM:
|
||||
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
|
||||
* RFC 3610 "Counter with CBC-MAC (CCM)"
|
||||
*
|
||||
* Related:
|
||||
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
|
||||
#include "mbedtls/ccm.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
#define CCM_ENCRYPT 0
|
||||
#define CCM_DECRYPT 1
|
||||
|
||||
/*
|
||||
* Initialize context
|
||||
*/
|
||||
void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
|
||||
}
|
||||
|
||||
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
|
||||
mbedtls_cipher_id_t cipher,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits )
|
||||
{
|
||||
int ret;
|
||||
const mbedtls_cipher_info_t *cipher_info;
|
||||
|
||||
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
|
||||
if( cipher_info == NULL )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
if( cipher_info->block_size != 16 )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
mbedtls_cipher_free( &ctx->cipher_ctx );
|
||||
|
||||
if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
|
||||
MBEDTLS_ENCRYPT ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Free context
|
||||
*/
|
||||
void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
|
||||
{
|
||||
mbedtls_cipher_free( &ctx->cipher_ctx );
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Macros for common operations.
|
||||
* Results in smaller compiled code than static inline functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Update the CBC-MAC state in y using a block in b
|
||||
* (Always using b as the source helps the compiler optimise a bit better.)
|
||||
*/
|
||||
#define UPDATE_CBC_MAC \
|
||||
for( i = 0; i < 16; i++ ) \
|
||||
y[i] ^= b[i]; \
|
||||
\
|
||||
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \
|
||||
return( ret );
|
||||
|
||||
/*
|
||||
* Encrypt or decrypt a partial block with CTR
|
||||
* Warning: using b for temporary storage! src and dst must not be b!
|
||||
* This avoids allocating one more 16 bytes buffer while allowing src == dst.
|
||||
*/
|
||||
#define CTR_CRYPT( dst, src, len ) \
|
||||
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \
|
||||
return( ret ); \
|
||||
\
|
||||
for( i = 0; i < len; i++ ) \
|
||||
dst[i] = src[i] ^ b[i];
|
||||
|
||||
/*
|
||||
* Authenticated encryption or decryption
|
||||
*/
|
||||
static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *add, size_t add_len,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
int ret;
|
||||
unsigned char i;
|
||||
unsigned char q;
|
||||
size_t len_left, olen;
|
||||
unsigned char b[16];
|
||||
unsigned char y[16];
|
||||
unsigned char ctr[16];
|
||||
const unsigned char *src;
|
||||
unsigned char *dst;
|
||||
|
||||
/*
|
||||
* Check length requirements: SP800-38C A.1
|
||||
* Additional requirement: a < 2^16 - 2^8 to simplify the code.
|
||||
* 'length' checked later (when writing it to the first block)
|
||||
*/
|
||||
if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
/* Also implies q is within bounds */
|
||||
if( iv_len < 7 || iv_len > 13 )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
if( add_len > 0xFF00 )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
q = 16 - 1 - (unsigned char) iv_len;
|
||||
|
||||
/*
|
||||
* First block B_0:
|
||||
* 0 .. 0 flags
|
||||
* 1 .. iv_len nonce (aka iv)
|
||||
* iv_len+1 .. 15 length
|
||||
*
|
||||
* With flags as (bits):
|
||||
* 7 0
|
||||
* 6 add present?
|
||||
* 5 .. 3 (t - 2) / 2
|
||||
* 2 .. 0 q - 1
|
||||
*/
|
||||
b[0] = 0;
|
||||
b[0] |= ( add_len > 0 ) << 6;
|
||||
b[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
|
||||
b[0] |= q - 1;
|
||||
|
||||
memcpy( b + 1, iv, iv_len );
|
||||
|
||||
for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
|
||||
b[15-i] = (unsigned char)( len_left & 0xFF );
|
||||
|
||||
if( len_left > 0 )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
|
||||
/* Start CBC-MAC with first block */
|
||||
memset( y, 0, 16 );
|
||||
UPDATE_CBC_MAC;
|
||||
|
||||
/*
|
||||
* If there is additional data, update CBC-MAC with
|
||||
* add_len, add, 0 (padding to a block boundary)
|
||||
*/
|
||||
if( add_len > 0 )
|
||||
{
|
||||
size_t use_len;
|
||||
len_left = add_len;
|
||||
src = add;
|
||||
|
||||
memset( b, 0, 16 );
|
||||
b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
|
||||
b[1] = (unsigned char)( ( add_len ) & 0xFF );
|
||||
|
||||
use_len = len_left < 16 - 2 ? len_left : 16 - 2;
|
||||
memcpy( b + 2, src, use_len );
|
||||
len_left -= use_len;
|
||||
src += use_len;
|
||||
|
||||
UPDATE_CBC_MAC;
|
||||
|
||||
while( len_left > 0 )
|
||||
{
|
||||
use_len = len_left > 16 ? 16 : len_left;
|
||||
|
||||
memset( b, 0, 16 );
|
||||
memcpy( b, src, use_len );
|
||||
UPDATE_CBC_MAC;
|
||||
|
||||
len_left -= use_len;
|
||||
src += use_len;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare counter block for encryption:
|
||||
* 0 .. 0 flags
|
||||
* 1 .. iv_len nonce (aka iv)
|
||||
* iv_len+1 .. 15 counter (initially 1)
|
||||
*
|
||||
* With flags as (bits):
|
||||
* 7 .. 3 0
|
||||
* 2 .. 0 q - 1
|
||||
*/
|
||||
ctr[0] = q - 1;
|
||||
memcpy( ctr + 1, iv, iv_len );
|
||||
memset( ctr + 1 + iv_len, 0, q );
|
||||
ctr[15] = 1;
|
||||
|
||||
/*
|
||||
* Authenticate and {en,de}crypt the message.
|
||||
*
|
||||
* The only difference between encryption and decryption is
|
||||
* the respective order of authentication and {en,de}cryption.
|
||||
*/
|
||||
len_left = length;
|
||||
src = input;
|
||||
dst = output;
|
||||
|
||||
while( len_left > 0 )
|
||||
{
|
||||
size_t use_len = len_left > 16 ? 16 : len_left;
|
||||
|
||||
if( mode == CCM_ENCRYPT )
|
||||
{
|
||||
memset( b, 0, 16 );
|
||||
memcpy( b, src, use_len );
|
||||
UPDATE_CBC_MAC;
|
||||
}
|
||||
|
||||
CTR_CRYPT( dst, src, use_len );
|
||||
|
||||
if( mode == CCM_DECRYPT )
|
||||
{
|
||||
memset( b, 0, 16 );
|
||||
memcpy( b, dst, use_len );
|
||||
UPDATE_CBC_MAC;
|
||||
}
|
||||
|
||||
dst += use_len;
|
||||
src += use_len;
|
||||
len_left -= use_len;
|
||||
|
||||
/*
|
||||
* Increment counter.
|
||||
* No need to check for overflow thanks to the length check above.
|
||||
*/
|
||||
for( i = 0; i < q; i++ )
|
||||
if( ++ctr[15-i] != 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Authentication: reset counter and crypt/mask internal tag
|
||||
*/
|
||||
for( i = 0; i < q; i++ )
|
||||
ctr[15-i] = 0;
|
||||
|
||||
CTR_CRYPT( y, y, 16 );
|
||||
memcpy( tag, y, tag_len );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticated encryption
|
||||
*/
|
||||
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *add, size_t add_len,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
|
||||
add, add_len, input, output, tag, tag_len ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticated decryption
|
||||
*/
|
||||
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *add, size_t add_len,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
const unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
int ret;
|
||||
unsigned char check_tag[16];
|
||||
unsigned char i;
|
||||
int diff;
|
||||
|
||||
if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
|
||||
iv, iv_len, add, add_len,
|
||||
input, output, check_tag, tag_len ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Check tag in "constant-time" */
|
||||
for( diff = 0, i = 0; i < tag_len; i++ )
|
||||
diff |= tag[i] ^ check_tag[i];
|
||||
|
||||
if( diff != 0 )
|
||||
{
|
||||
mbedtls_zeroize( output, length );
|
||||
return( MBEDTLS_ERR_CCM_AUTH_FAILED );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||
/*
|
||||
* Examples 1 to 3 from SP800-38C Appendix C
|
||||
*/
|
||||
|
||||
#define NB_TESTS 3
|
||||
|
||||
/*
|
||||
* The data is the same for all tests, only the used length changes
|
||||
*/
|
||||
static const unsigned char key[] = {
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
|
||||
};
|
||||
|
||||
static const unsigned char iv[] = {
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b
|
||||
};
|
||||
|
||||
static const unsigned char ad[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13
|
||||
};
|
||||
|
||||
static const unsigned char msg[] = {
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
};
|
||||
|
||||
static const size_t iv_len [NB_TESTS] = { 7, 8, 12 };
|
||||
static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
|
||||
static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
|
||||
static const size_t tag_len[NB_TESTS] = { 4, 6, 8 };
|
||||
|
||||
static const unsigned char res[NB_TESTS][32] = {
|
||||
{ 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
|
||||
{ 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
|
||||
0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
|
||||
0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd },
|
||||
{ 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a,
|
||||
0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b,
|
||||
0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5,
|
||||
0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 }
|
||||
};
|
||||
|
||||
int mbedtls_ccm_self_test( int verbose )
|
||||
{
|
||||
mbedtls_ccm_context ctx;
|
||||
unsigned char out[32];
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
mbedtls_ccm_init( &ctx );
|
||||
|
||||
if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
mbedtls_printf( " CCM: setup failed" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
for( i = 0; i < NB_TESTS; i++ )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 );
|
||||
|
||||
ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i],
|
||||
iv, iv_len[i], ad, add_len[i],
|
||||
msg, out,
|
||||
out + msg_len[i], tag_len[i] );
|
||||
|
||||
if( ret != 0 ||
|
||||
memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
mbedtls_printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i],
|
||||
iv, iv_len[i], ad, add_len[i],
|
||||
res[i], out,
|
||||
res[i] + msg_len[i], tag_len[i] );
|
||||
|
||||
if( ret != 0 ||
|
||||
memcmp( out, msg, msg_len[i] ) != 0 )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
mbedtls_printf( "failed\n" );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( verbose != 0 )
|
||||
mbedtls_printf( "passed\n" );
|
||||
}
|
||||
|
||||
mbedtls_ccm_free( &ctx );
|
||||
|
||||
if( verbose != 0 )
|
||||
mbedtls_printf( "\n" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
|
||||
|
||||
#endif /* MBEDTLS_CCM_C */
|
|
@ -0,0 +1,917 @@
|
|||
/**
|
||||
* \file cipher.c
|
||||
*
|
||||
* \brief Generic cipher wrapper for mbed TLS
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_C)
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
#include "mbedtls/cipher_internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
#include "mbedtls/gcm.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
#include "mbedtls/ccm.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CMAC_C)
|
||||
#include "mbedtls/cmac.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
|
||||
#define MBEDTLS_CIPHER_MODE_STREAM
|
||||
#endif
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
static int supported_init = 0;
|
||||
|
||||
const int *mbedtls_cipher_list( void )
|
||||
{
|
||||
const mbedtls_cipher_definition_t *def;
|
||||
int *type;
|
||||
|
||||
if( ! supported_init )
|
||||
{
|
||||
def = mbedtls_cipher_definitions;
|
||||
type = mbedtls_cipher_supported;
|
||||
|
||||
while( def->type != 0 )
|
||||
*type++ = (*def++).type;
|
||||
|
||||
*type = 0;
|
||||
|
||||
supported_init = 1;
|
||||
}
|
||||
|
||||
return( mbedtls_cipher_supported );
|
||||
}
|
||||
|
||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type )
|
||||
{
|
||||
const mbedtls_cipher_definition_t *def;
|
||||
|
||||
for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
|
||||
if( def->type == cipher_type )
|
||||
return( def->info );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name )
|
||||
{
|
||||
const mbedtls_cipher_definition_t *def;
|
||||
|
||||
if( NULL == cipher_name )
|
||||
return( NULL );
|
||||
|
||||
for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
|
||||
if( ! strcmp( def->info->name, cipher_name ) )
|
||||
return( def->info );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
|
||||
int key_bitlen,
|
||||
const mbedtls_cipher_mode_t mode )
|
||||
{
|
||||
const mbedtls_cipher_definition_t *def;
|
||||
|
||||
for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
|
||||
if( def->info->base->cipher == cipher_id &&
|
||||
def->info->key_bitlen == (unsigned) key_bitlen &&
|
||||
def->info->mode == mode )
|
||||
return( def->info );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
|
||||
}
|
||||
|
||||
void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
#if defined(MBEDTLS_CMAC_C)
|
||||
if( ctx->cmac_ctx )
|
||||
{
|
||||
mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) );
|
||||
mbedtls_free( ctx->cmac_ctx );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( ctx->cipher_ctx )
|
||||
ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
|
||||
|
||||
mbedtls_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
|
||||
}
|
||||
|
||||
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
|
||||
{
|
||||
if( NULL == cipher_info || NULL == ctx )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
|
||||
|
||||
if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
|
||||
return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
|
||||
|
||||
ctx->cipher_info = cipher_info;
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
|
||||
/*
|
||||
* Ignore possible errors caused by a cipher mode that doesn't use padding
|
||||
*/
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
|
||||
(void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
|
||||
#else
|
||||
(void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
|
||||
#endif
|
||||
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
|
||||
int key_bitlen, const mbedtls_operation_t operation )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
|
||||
(int) ctx->cipher_info->key_bitlen != key_bitlen )
|
||||
{
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
ctx->key_bitlen = key_bitlen;
|
||||
ctx->operation = operation;
|
||||
|
||||
/*
|
||||
* For CFB and CTR mode always use the encryption key schedule
|
||||
*/
|
||||
if( MBEDTLS_ENCRYPT == operation ||
|
||||
MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
|
||||
MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
|
||||
{
|
||||
return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
|
||||
ctx->key_bitlen );
|
||||
}
|
||||
|
||||
if( MBEDTLS_DECRYPT == operation )
|
||||
return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
|
||||
ctx->key_bitlen );
|
||||
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *iv, size_t iv_len )
|
||||
{
|
||||
size_t actual_iv_size;
|
||||
|
||||
if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
/* avoid buffer overflow in ctx->iv */
|
||||
if( iv_len > MBEDTLS_MAX_IV_LENGTH )
|
||||
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||
|
||||
if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
|
||||
actual_iv_size = iv_len;
|
||||
else
|
||||
{
|
||||
actual_iv_size = ctx->cipher_info->iv_size;
|
||||
|
||||
/* avoid reading past the end of input buffer */
|
||||
if( actual_iv_size > iv_len )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
memcpy( ctx->iv, iv, actual_iv_size );
|
||||
ctx->iv_size = actual_iv_size;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
ctx->unprocessed_len = 0;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *ad, size_t ad_len )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
|
||||
{
|
||||
return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
|
||||
ctx->iv, ctx->iv_size, ad, ad_len );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
|
||||
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
|
||||
size_t ilen, unsigned char *output, size_t *olen )
|
||||
{
|
||||
int ret;
|
||||
size_t block_size = 0;
|
||||
|
||||
if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
|
||||
{
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
*olen = 0;
|
||||
block_size = mbedtls_cipher_get_block_size( ctx );
|
||||
|
||||
if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
|
||||
{
|
||||
if( ilen != block_size )
|
||||
return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
|
||||
|
||||
*olen = ilen;
|
||||
|
||||
if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
|
||||
ctx->operation, input, output ) ) )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
|
||||
{
|
||||
*olen = ilen;
|
||||
return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
|
||||
output );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( 0 == block_size )
|
||||
{
|
||||
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
|
||||
}
|
||||
|
||||
if( input == output &&
|
||||
( ctx->unprocessed_len != 0 || ilen % block_size ) )
|
||||
{
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
|
||||
{
|
||||
size_t copy_len = 0;
|
||||
|
||||
/*
|
||||
* If there is not enough data for a full block, cache it.
|
||||
*/
|
||||
if( ( ctx->operation == MBEDTLS_DECRYPT &&
|
||||
ilen + ctx->unprocessed_len <= block_size ) ||
|
||||
( ctx->operation == MBEDTLS_ENCRYPT &&
|
||||
ilen + ctx->unprocessed_len < block_size ) )
|
||||
{
|
||||
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
|
||||
ilen );
|
||||
|
||||
ctx->unprocessed_len += ilen;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Process cached data first
|
||||
*/
|
||||
if( 0 != ctx->unprocessed_len )
|
||||
{
|
||||
copy_len = block_size - ctx->unprocessed_len;
|
||||
|
||||
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
|
||||
copy_len );
|
||||
|
||||
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
|
||||
ctx->operation, block_size, ctx->iv,
|
||||
ctx->unprocessed_data, output ) ) )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*olen += block_size;
|
||||
output += block_size;
|
||||
ctx->unprocessed_len = 0;
|
||||
|
||||
input += copy_len;
|
||||
ilen -= copy_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache final, incomplete block
|
||||
*/
|
||||
if( 0 != ilen )
|
||||
{
|
||||
if( 0 == block_size )
|
||||
{
|
||||
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
|
||||
}
|
||||
|
||||
copy_len = ilen % block_size;
|
||||
if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT )
|
||||
copy_len = block_size;
|
||||
|
||||
memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
|
||||
copy_len );
|
||||
|
||||
ctx->unprocessed_len += copy_len;
|
||||
ilen -= copy_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process remaining full blocks
|
||||
*/
|
||||
if( ilen )
|
||||
{
|
||||
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
|
||||
ctx->operation, ilen, ctx->iv, input, output ) ) )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*olen += ilen;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
|
||||
{
|
||||
if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
|
||||
ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
|
||||
input, output ) ) )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*olen = ilen;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||
if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
|
||||
{
|
||||
if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
|
||||
ilen, &ctx->unprocessed_len, ctx->iv,
|
||||
ctx->unprocessed_data, input, output ) ) )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*olen = ilen;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
|
||||
if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
|
||||
{
|
||||
if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
|
||||
ilen, input, output ) ) )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*olen = ilen;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_STREAM */
|
||||
|
||||
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
|
||||
/*
|
||||
* PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
|
||||
*/
|
||||
static void add_pkcs_padding( unsigned char *output, size_t output_len,
|
||||
size_t data_len )
|
||||
{
|
||||
size_t padding_len = output_len - data_len;
|
||||
unsigned char i;
|
||||
|
||||
for( i = 0; i < padding_len; i++ )
|
||||
output[data_len + i] = (unsigned char) padding_len;
|
||||
}
|
||||
|
||||
static int get_pkcs_padding( unsigned char *input, size_t input_len,
|
||||
size_t *data_len )
|
||||
{
|
||||
size_t i, pad_idx;
|
||||
unsigned char padding_len, bad = 0;
|
||||
|
||||
if( NULL == input || NULL == data_len )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
padding_len = input[input_len - 1];
|
||||
*data_len = input_len - padding_len;
|
||||
|
||||
/* Avoid logical || since it results in a branch */
|
||||
bad |= padding_len > input_len;
|
||||
bad |= padding_len == 0;
|
||||
|
||||
/* The number of bytes checked must be independent of padding_len,
|
||||
* so pick input_len, which is usually 8 or 16 (one block) */
|
||||
pad_idx = input_len - padding_len;
|
||||
for( i = 0; i < input_len; i++ )
|
||||
bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
|
||||
|
||||
return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
|
||||
/*
|
||||
* One and zeros padding: fill with 80 00 ... 00
|
||||
*/
|
||||
static void add_one_and_zeros_padding( unsigned char *output,
|
||||
size_t output_len, size_t data_len )
|
||||
{
|
||||
size_t padding_len = output_len - data_len;
|
||||
unsigned char i = 0;
|
||||
|
||||
output[data_len] = 0x80;
|
||||
for( i = 1; i < padding_len; i++ )
|
||||
output[data_len + i] = 0x00;
|
||||
}
|
||||
|
||||
static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
|
||||
size_t *data_len )
|
||||
{
|
||||
size_t i;
|
||||
unsigned char done = 0, prev_done, bad;
|
||||
|
||||
if( NULL == input || NULL == data_len )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
bad = 0xFF;
|
||||
*data_len = 0;
|
||||
for( i = input_len; i > 0; i-- )
|
||||
{
|
||||
prev_done = done;
|
||||
done |= ( input[i-1] != 0 );
|
||||
*data_len |= ( i - 1 ) * ( done != prev_done );
|
||||
bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done );
|
||||
}
|
||||
|
||||
return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
|
||||
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
|
||||
/*
|
||||
* Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
|
||||
*/
|
||||
static void add_zeros_and_len_padding( unsigned char *output,
|
||||
size_t output_len, size_t data_len )
|
||||
{
|
||||
size_t padding_len = output_len - data_len;
|
||||
unsigned char i = 0;
|
||||
|
||||
for( i = 1; i < padding_len; i++ )
|
||||
output[data_len + i - 1] = 0x00;
|
||||
output[output_len - 1] = (unsigned char) padding_len;
|
||||
}
|
||||
|
||||
static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
|
||||
size_t *data_len )
|
||||
{
|
||||
size_t i, pad_idx;
|
||||
unsigned char padding_len, bad = 0;
|
||||
|
||||
if( NULL == input || NULL == data_len )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
padding_len = input[input_len - 1];
|
||||
*data_len = input_len - padding_len;
|
||||
|
||||
/* Avoid logical || since it results in a branch */
|
||||
bad |= padding_len > input_len;
|
||||
bad |= padding_len == 0;
|
||||
|
||||
/* The number of bytes checked must be independent of padding_len */
|
||||
pad_idx = input_len - padding_len;
|
||||
for( i = 0; i < input_len - 1; i++ )
|
||||
bad |= input[i] * ( i >= pad_idx );
|
||||
|
||||
return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
|
||||
/*
|
||||
* Zero padding: fill with 00 ... 00
|
||||
*/
|
||||
static void add_zeros_padding( unsigned char *output,
|
||||
size_t output_len, size_t data_len )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for( i = data_len; i < output_len; i++ )
|
||||
output[i] = 0x00;
|
||||
}
|
||||
|
||||
static int get_zeros_padding( unsigned char *input, size_t input_len,
|
||||
size_t *data_len )
|
||||
{
|
||||
size_t i;
|
||||
unsigned char done = 0, prev_done;
|
||||
|
||||
if( NULL == input || NULL == data_len )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
*data_len = 0;
|
||||
for( i = input_len; i > 0; i-- )
|
||||
{
|
||||
prev_done = done;
|
||||
done |= ( input[i-1] != 0 );
|
||||
*data_len |= i * ( done != prev_done );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
|
||||
|
||||
/*
|
||||
* No padding: don't pad :)
|
||||
*
|
||||
* There is no add_padding function (check for NULL in mbedtls_cipher_finish)
|
||||
* but a trivial get_padding function
|
||||
*/
|
||||
static int get_no_padding( unsigned char *input, size_t input_len,
|
||||
size_t *data_len )
|
||||
{
|
||||
if( NULL == input || NULL == data_len )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
*data_len = input_len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
|
||||
|
||||
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
|
||||
unsigned char *output, size_t *olen )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
*olen = 0;
|
||||
|
||||
if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
|
||||
MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
|
||||
MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
|
||||
MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
|
||||
{
|
||||
if( ctx->unprocessed_len != 0 )
|
||||
return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if( MBEDTLS_ENCRYPT == ctx->operation )
|
||||
{
|
||||
/* check for 'no padding' mode */
|
||||
if( NULL == ctx->add_padding )
|
||||
{
|
||||
if( 0 != ctx->unprocessed_len )
|
||||
return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
|
||||
ctx->unprocessed_len );
|
||||
}
|
||||
else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
|
||||
{
|
||||
/*
|
||||
* For decrypt operations, expect a full block,
|
||||
* or an empty block if no padding
|
||||
*/
|
||||
if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
|
||||
return( 0 );
|
||||
|
||||
return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
|
||||
}
|
||||
|
||||
/* cipher block */
|
||||
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
|
||||
ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
|
||||
ctx->unprocessed_data, output ) ) )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Set output size for decryption */
|
||||
if( MBEDTLS_DECRYPT == ctx->operation )
|
||||
return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
|
||||
olen );
|
||||
|
||||
/* Set output size for encryption */
|
||||
*olen = mbedtls_cipher_get_block_size( ctx );
|
||||
return( 0 );
|
||||
}
|
||||
#else
|
||||
((void) output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
|
||||
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode )
|
||||
{
|
||||
if( NULL == ctx ||
|
||||
MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
|
||||
{
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
switch( mode )
|
||||
{
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
|
||||
case MBEDTLS_PADDING_PKCS7:
|
||||
ctx->add_padding = add_pkcs_padding;
|
||||
ctx->get_padding = get_pkcs_padding;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
|
||||
case MBEDTLS_PADDING_ONE_AND_ZEROS:
|
||||
ctx->add_padding = add_one_and_zeros_padding;
|
||||
ctx->get_padding = get_one_and_zeros_padding;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
|
||||
case MBEDTLS_PADDING_ZEROS_AND_LEN:
|
||||
ctx->add_padding = add_zeros_and_len_padding;
|
||||
ctx->get_padding = get_zeros_and_len_padding;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
|
||||
case MBEDTLS_PADDING_ZEROS:
|
||||
ctx->add_padding = add_zeros_padding;
|
||||
ctx->get_padding = get_zeros_padding;
|
||||
break;
|
||||
#endif
|
||||
case MBEDTLS_PADDING_NONE:
|
||||
ctx->add_padding = NULL;
|
||||
ctx->get_padding = get_no_padding;
|
||||
break;
|
||||
|
||||
default:
|
||||
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
|
||||
unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
if( MBEDTLS_ENCRYPT != ctx->operation )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
|
||||
return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( NULL == ctx || NULL == ctx->cipher_info ||
|
||||
MBEDTLS_DECRYPT != ctx->operation )
|
||||
{
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
|
||||
{
|
||||
unsigned char check_tag[16];
|
||||
size_t i;
|
||||
int diff;
|
||||
|
||||
if( tag_len > sizeof( check_tag ) )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
|
||||
check_tag, tag_len ) ) )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Check the tag in "constant-time" */
|
||||
for( diff = 0, i = 0; i < tag_len; i++ )
|
||||
diff |= tag[i] ^ check_tag[i];
|
||||
|
||||
if( diff != 0 )
|
||||
return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
|
||||
/*
|
||||
* Packet-oriented wrapper for non-AEAD modes
|
||||
*/
|
||||
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen )
|
||||
{
|
||||
int ret;
|
||||
size_t finish_olen;
|
||||
|
||||
if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
*olen += finish_olen;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
|
||||
/*
|
||||
* Packet-oriented encryption for AEAD modes
|
||||
*/
|
||||
int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *ad, size_t ad_len,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen,
|
||||
unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
|
||||
{
|
||||
*olen = ilen;
|
||||
return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen,
|
||||
iv, iv_len, ad, ad_len, input, output,
|
||||
tag_len, tag ) );
|
||||
}
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
|
||||
{
|
||||
*olen = ilen;
|
||||
return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
|
||||
iv, iv_len, ad, ad_len, input, output,
|
||||
tag, tag_len ) );
|
||||
}
|
||||
#endif /* MBEDTLS_CCM_C */
|
||||
|
||||
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
|
||||
/*
|
||||
* Packet-oriented decryption for AEAD modes
|
||||
*/
|
||||
int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *ad, size_t ad_len,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen,
|
||||
const unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
|
||||
{
|
||||
int ret;
|
||||
|
||||
*olen = ilen;
|
||||
ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
|
||||
iv, iv_len, ad, ad_len,
|
||||
tag, tag_len, input, output );
|
||||
|
||||
if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
|
||||
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
|
||||
{
|
||||
int ret;
|
||||
|
||||
*olen = ilen;
|
||||
ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
|
||||
iv, iv_len, ad, ad_len,
|
||||
input, output, tag, tag_len );
|
||||
|
||||
if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
|
||||
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_CCM_C */
|
||||
|
||||
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
|
||||
|
||||
#endif /* MBEDTLS_CIPHER_C */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,4 @@
|
|||
# Ethernet Arduino Library for ESP32
|
||||
|
||||
See https://github.com/espressif/arduino-esp32/issues/3554#issuecomment-596902806
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
#include <ETH.h>
|
||||
|
||||
#define ETH_ADDR 1
|
||||
#define ETH_POWER_PIN 5
|
||||
#define ETH_MDC_PIN 23
|
||||
#define ETH_MDIO_PIN 18
|
||||
#define ETH_TYPE ETH_PHY_IP101
|
||||
|
||||
static bool eth_connected = false;
|
||||
|
||||
void WiFiEvent(WiFiEvent_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case SYSTEM_EVENT_ETH_START:
|
||||
Serial.println("ETH Started");
|
||||
//set eth hostname here
|
||||
ETH.setHostname("esp32-ethernet");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_CONNECTED:
|
||||
Serial.println("ETH Connected");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||
Serial.print("ETH MAC: ");
|
||||
Serial.print(ETH.macAddress());
|
||||
Serial.print(", IPv4: ");
|
||||
Serial.print(ETH.localIP());
|
||||
if (ETH.fullDuplex()) {
|
||||
Serial.print(", FULL_DUPLEX");
|
||||
}
|
||||
Serial.print(", ");
|
||||
Serial.print(ETH.linkSpeed());
|
||||
Serial.println("Mbps");
|
||||
eth_connected = true;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||
Serial.println("ETH Disconnected");
|
||||
eth_connected = false;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_STOP:
|
||||
Serial.println("ETH Stopped");
|
||||
eth_connected = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void testClient(const char * host, uint16_t port)
|
||||
{
|
||||
Serial.print("\nconnecting to ");
|
||||
Serial.println(host);
|
||||
|
||||
WiFiClient client;
|
||||
if (!client.connect(host, port)) {
|
||||
Serial.println("connection failed");
|
||||
return;
|
||||
}
|
||||
client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
|
||||
while (client.connected() && !client.available());
|
||||
while (client.available()) {
|
||||
Serial.write(client.read());
|
||||
}
|
||||
|
||||
Serial.println("closing connection\n");
|
||||
client.stop();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (eth_connected) {
|
||||
testClient("google.com", 80);
|
||||
}
|
||||
delay(10000);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
name=ESP32 Ethernet
|
||||
|
||||
version=1.1.0
|
||||
|
||||
author=Espressif
|
||||
|
||||
maintainer=Espressif
|
||||
|
||||
sentence=Ethernet Library for ESP32
|
||||
|
||||
paragraph=This library allows ESP32 to use ethernet hardware
|
||||
|
||||
category=Communication
|
||||
|
||||
url=
|
||||
|
||||
architectures=esp32
|
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
ETH.h - espre ETH PHY support.
|
||||
Based on WiFi.h from Arduino WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. 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
|
||||
*/
|
||||
|
||||
#include "ETH.h"
|
||||
#include "eth_phy/phy.h"
|
||||
#include "eth_phy/phy_tlk110.h"
|
||||
#include "eth_phy/phy_lan8720.h"
|
||||
#include "eth_phy/phy_ip101.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/dns.h"
|
||||
|
||||
extern void tcpipInit();
|
||||
|
||||
static int _eth_phy_mdc_pin = -1;
|
||||
static int _eth_phy_mdio_pin = -1;
|
||||
static int _eth_phy_power_pin = -1;
|
||||
static eth_phy_power_enable_func _eth_phy_power_enable_orig = NULL;
|
||||
|
||||
static void _eth_phy_config_gpio(void)
|
||||
{
|
||||
if(_eth_phy_mdc_pin < 0 || _eth_phy_mdio_pin < 0){
|
||||
log_e("MDC and MDIO pins are not configured!");
|
||||
return;
|
||||
}
|
||||
phy_rmii_configure_data_interface_pins();
|
||||
phy_rmii_smi_configure_pins(_eth_phy_mdc_pin, _eth_phy_mdio_pin);
|
||||
}
|
||||
|
||||
static void _eth_phy_power_enable(bool enable)
|
||||
{
|
||||
pinMode(_eth_phy_power_pin, OUTPUT);
|
||||
digitalWrite(_eth_phy_power_pin, enable);
|
||||
delay(1);
|
||||
}
|
||||
|
||||
ETHClass::ETHClass():initialized(false),started(false),staticIP(false)
|
||||
{
|
||||
}
|
||||
|
||||
ETHClass::~ETHClass()
|
||||
{}
|
||||
|
||||
bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode)
|
||||
{
|
||||
esp_err_t err;
|
||||
if(initialized){
|
||||
err = esp_eth_enable();
|
||||
if(err){
|
||||
log_e("esp_eth_enable error: %d", err);
|
||||
return false;
|
||||
}
|
||||
started = true;
|
||||
return true;
|
||||
}
|
||||
_eth_phy_mdc_pin = mdc;
|
||||
_eth_phy_mdio_pin = mdio;
|
||||
_eth_phy_power_pin = power;
|
||||
|
||||
if(type == ETH_PHY_LAN8720)
|
||||
{
|
||||
eth_config_t config = phy_lan8720_default_ethernet_config;
|
||||
memcpy(ð_config, &config, sizeof(eth_config_t));
|
||||
}
|
||||
else if(type == ETH_PHY_TLK110)
|
||||
{
|
||||
eth_config_t config = phy_tlk110_default_ethernet_config;
|
||||
memcpy(ð_config, &config, sizeof(eth_config_t));
|
||||
}
|
||||
else if(type == ETH_PHY_IP101)
|
||||
{
|
||||
eth_config_t config = phy_ip101_default_ethernet_config;
|
||||
memcpy(ð_config, &config, sizeof(eth_config_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
log_e("Bad ETH_PHY type: %u", (uint8_t)type);
|
||||
return false;
|
||||
}
|
||||
|
||||
eth_config.phy_addr = (eth_phy_base_t)phy_addr;
|
||||
eth_config.clock_mode = clock_mode;
|
||||
eth_config.gpio_config = _eth_phy_config_gpio;
|
||||
eth_config.tcpip_input = tcpip_adapter_eth_input;
|
||||
if(_eth_phy_power_pin >= 0){
|
||||
_eth_phy_power_enable_orig = eth_config.phy_power_enable;
|
||||
eth_config.phy_power_enable = _eth_phy_power_enable;
|
||||
}
|
||||
|
||||
tcpipInit();
|
||||
err = esp_eth_init(ð_config);
|
||||
if(!err){
|
||||
initialized = true;
|
||||
err = esp_eth_enable();
|
||||
if(err){
|
||||
log_e("esp_eth_enable error: %d", err);
|
||||
} else {
|
||||
started = true;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
log_e("esp_eth_init error: %d", err);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
tcpip_adapter_ip_info_t info;
|
||||
|
||||
if(local_ip != (uint32_t)0x00000000){
|
||||
info.ip.addr = static_cast<uint32_t>(local_ip);
|
||||
info.gw.addr = static_cast<uint32_t>(gateway);
|
||||
info.netmask.addr = static_cast<uint32_t>(subnet);
|
||||
} else {
|
||||
info.ip.addr = 0;
|
||||
info.gw.addr = 0;
|
||||
info.netmask.addr = 0;
|
||||
}
|
||||
|
||||
err = tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_ETH);
|
||||
if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED){
|
||||
log_e("DHCP could not be stopped! Error: %d", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
err = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_ETH, &info);
|
||||
if(err != ERR_OK){
|
||||
log_e("STA IP could not be configured! Error: %d", err);
|
||||
return false;
|
||||
}
|
||||
if(info.ip.addr){
|
||||
staticIP = true;
|
||||
} else {
|
||||
err = tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_ETH);
|
||||
if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED){
|
||||
log_w("DHCP could not be started! Error: %d", err);
|
||||
return false;
|
||||
}
|
||||
staticIP = false;
|
||||
}
|
||||
|
||||
ip_addr_t d;
|
||||
d.type = IPADDR_TYPE_V4;
|
||||
|
||||
if(dns1 != (uint32_t)0x00000000) {
|
||||
// Set DNS1-Server
|
||||
d.u_addr.ip4.addr = static_cast<uint32_t>(dns1);
|
||||
dns_setserver(0, &d);
|
||||
}
|
||||
|
||||
if(dns2 != (uint32_t)0x00000000) {
|
||||
// Set DNS2-Server
|
||||
d.u_addr.ip4.addr = static_cast<uint32_t>(dns2);
|
||||
dns_setserver(1, &d);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
IPAddress ETHClass::localIP()
|
||||
{
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){
|
||||
return IPAddress();
|
||||
}
|
||||
return IPAddress(ip.ip.addr);
|
||||
}
|
||||
|
||||
IPAddress ETHClass::subnetMask()
|
||||
{
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){
|
||||
return IPAddress();
|
||||
}
|
||||
return IPAddress(ip.netmask.addr);
|
||||
}
|
||||
|
||||
IPAddress ETHClass::gatewayIP()
|
||||
{
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){
|
||||
return IPAddress();
|
||||
}
|
||||
return IPAddress(ip.gw.addr);
|
||||
}
|
||||
|
||||
IPAddress ETHClass::dnsIP(uint8_t dns_no)
|
||||
{
|
||||
ip_addr_t dns_ip = dns_getserver(dns_no);
|
||||
return IPAddress(dns_ip.u_addr.ip4.addr);
|
||||
}
|
||||
|
||||
IPAddress ETHClass::broadcastIP()
|
||||
{
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){
|
||||
return IPAddress();
|
||||
}
|
||||
return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
|
||||
}
|
||||
|
||||
IPAddress ETHClass::networkID()
|
||||
{
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){
|
||||
return IPAddress();
|
||||
}
|
||||
return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
|
||||
}
|
||||
|
||||
uint8_t ETHClass::subnetCIDR()
|
||||
{
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){
|
||||
return (uint8_t)0;
|
||||
}
|
||||
return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr));
|
||||
}
|
||||
|
||||
const char * ETHClass::getHostname()
|
||||
{
|
||||
const char * hostname;
|
||||
if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_ETH, &hostname)){
|
||||
return NULL;
|
||||
}
|
||||
return hostname;
|
||||
}
|
||||
|
||||
bool ETHClass::setHostname(const char * hostname)
|
||||
{
|
||||
return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_ETH, hostname) == 0;
|
||||
}
|
||||
|
||||
bool ETHClass::fullDuplex()
|
||||
{
|
||||
return eth_config.phy_get_duplex_mode();
|
||||
}
|
||||
|
||||
bool ETHClass::linkUp()
|
||||
{
|
||||
return eth_config.phy_check_link();
|
||||
}
|
||||
|
||||
uint8_t ETHClass::linkSpeed()
|
||||
{
|
||||
return eth_config.phy_get_speed_mode()?100:10;
|
||||
}
|
||||
|
||||
bool ETHClass::enableIpV6()
|
||||
{
|
||||
return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_ETH) == 0;
|
||||
}
|
||||
|
||||
IPv6Address ETHClass::localIPv6()
|
||||
{
|
||||
static ip6_addr_t addr;
|
||||
if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_ETH, &addr)){
|
||||
return IPv6Address();
|
||||
}
|
||||
return IPv6Address(addr.addr);
|
||||
}
|
||||
|
||||
uint8_t * macAddress(uint8_t* mac)
|
||||
{
|
||||
if(!mac){
|
||||
return NULL;
|
||||
}
|
||||
esp_eth_get_mac(mac);
|
||||
return mac;
|
||||
}
|
||||
|
||||
String ETHClass::macAddress(void)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
char macStr[18] = { 0 };
|
||||
esp_eth_get_mac(mac);
|
||||
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
return String(macStr);
|
||||
}
|
||||
|
||||
ETHClass ETH;
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
ETH.h - espre ETH PHY support.
|
||||
Based on WiFi.h from Ardiono WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. 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 _ETH_H_
|
||||
#define _ETH_H_
|
||||
|
||||
#include "WiFi.h"
|
||||
#include "esp_eth.h"
|
||||
|
||||
#ifndef ETH_PHY_ADDR
|
||||
#define ETH_PHY_ADDR 0
|
||||
#endif
|
||||
|
||||
#ifndef ETH_PHY_TYPE
|
||||
#define ETH_PHY_TYPE ETH_PHY_LAN8720
|
||||
#endif
|
||||
|
||||
#ifndef ETH_PHY_POWER
|
||||
#define ETH_PHY_POWER -1
|
||||
#endif
|
||||
|
||||
#ifndef ETH_PHY_MDC
|
||||
#define ETH_PHY_MDC 23
|
||||
#endif
|
||||
|
||||
#ifndef ETH_PHY_MDIO
|
||||
#define ETH_PHY_MDIO 18
|
||||
#endif
|
||||
|
||||
#ifndef ETH_CLK_MODE
|
||||
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
|
||||
#endif
|
||||
|
||||
typedef enum { ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_IP101, ETH_PHY_MAX } eth_phy_type_t;
|
||||
|
||||
class ETHClass {
|
||||
private:
|
||||
bool initialized;
|
||||
bool started;
|
||||
bool staticIP;
|
||||
eth_config_t eth_config;
|
||||
public:
|
||||
ETHClass();
|
||||
~ETHClass();
|
||||
|
||||
bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO, eth_phy_type_t type=ETH_PHY_TYPE, eth_clock_mode_t clk_mode=ETH_CLK_MODE);
|
||||
|
||||
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);
|
||||
|
||||
const char * getHostname();
|
||||
bool setHostname(const char * hostname);
|
||||
|
||||
bool fullDuplex();
|
||||
bool linkUp();
|
||||
uint8_t linkSpeed();
|
||||
|
||||
bool enableIpV6();
|
||||
IPv6Address localIPv6();
|
||||
|
||||
IPAddress localIP();
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsIP(uint8_t dns_no = 0);
|
||||
|
||||
IPAddress broadcastIP();
|
||||
IPAddress networkID();
|
||||
uint8_t subnetCIDR();
|
||||
|
||||
uint8_t * macAddress(uint8_t* mac);
|
||||
String macAddress();
|
||||
|
||||
friend class WiFiClient;
|
||||
friend class WiFiServer;
|
||||
};
|
||||
|
||||
extern ETHClass ETH;
|
||||
|
||||
#endif /* _ETH_H_ */
|
|
@ -128,6 +128,6 @@ build_flags = ${tasmota_core.build_flags}
|
|||
|
||||
[tasmota_core]
|
||||
; *** Esp8266 Arduino core 2.7.1
|
||||
platform = espressif8266@2.5.1
|
||||
platform = espressif8266@2.5.2
|
||||
platform_packages =
|
||||
build_flags = ${esp82xx_defaults.build_flags}
|
||||
|
|
|
@ -1,5 +1,31 @@
|
|||
## Unreleased (development)
|
||||
|
||||
### 8.3.1.6 20200617
|
||||
|
||||
- Add command ``Module2`` to configure fallback module on fast reboot (#8464)
|
||||
- Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff
|
||||
- Add library to be used for decoding Teleinfo (French Metering Smart Meter)
|
||||
- Add support for single wire LMT01 temperature Sensor by justifiably (#8713)
|
||||
- Change ESP32 USER GPIO template representation decreasing template message size
|
||||
- Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT
|
||||
- Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset``
|
||||
|
||||
### 8.3.1.5 20200616
|
||||
|
||||
- Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3``
|
||||
- Add Zigbee initial support for EmberZNet protocol (raw send/receive only)
|
||||
|
||||
### 8.3.1.4 20200615
|
||||
|
||||
- Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON
|
||||
|
||||
### 8.3.1.3 20200611
|
||||
|
||||
- Add initial support for Telegram bot (#8619)
|
||||
- Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638)
|
||||
- Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet
|
||||
- Add serial to TCP bridge, ``TCPStart`` and ``TCPBaudRate`` (needs #define USE_TCP_BRIDGE)
|
||||
|
||||
### 8.3.1.2 20200522
|
||||
|
||||
- Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]``
|
||||
|
|
|
@ -40,7 +40,7 @@ uint32_t *stack_thunk_light_save = NULL; /* Saved A1 while in BearSSL */
|
|||
uint32_t stack_thunk_light_refcnt = 0;
|
||||
|
||||
//#define _stackSize (5600/4)
|
||||
#if defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_TLS_FORCE_EC_CIPHER)
|
||||
#ifdef USE_MQTT_TLS_FORCE_EC_CIPHER
|
||||
#define _stackSize (5300/4) // using a light version of bearssl we can save 300 bytes
|
||||
#else
|
||||
#define _stackSize (3600/4) // using a light version of bearssl we can save 2k
|
||||
|
|
|
@ -52,7 +52,7 @@ extern uint32_t stack_thunk_light_refcnt;
|
|||
|
||||
// Thunking macro
|
||||
#define make_stack_thunk_light(fcnToThunk) \
|
||||
__asm("\n\
|
||||
__asm__("\n\
|
||||
.text\n\
|
||||
.literal_position\n\
|
||||
.literal .LC_STACK_VALUE"#fcnToThunk", 0xdeadbeef\n\
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,221 +1,221 @@
|
|||
/*
|
||||
WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries
|
||||
- Mostly compatible with Arduino WiFi shield library and standard
|
||||
WiFiClient/ServerSecure (except for certificate handling).
|
||||
|
||||
Copyright (c) 2018 Earle F. Philhower, III
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#include <core_version.h>
|
||||
|
||||
#ifndef wificlientlightbearssl_h
|
||||
#define wificlientlightbearssl_h
|
||||
#if defined(USE_MQTT_TLS) || defined (USE_SENDMAIL)
|
||||
#include <vector>
|
||||
#include "WiFiClient.h"
|
||||
#include <t_bearssl.h>
|
||||
|
||||
namespace BearSSL {
|
||||
|
||||
class WiFiClientSecure_light : public WiFiClient {
|
||||
public:
|
||||
WiFiClientSecure_light(int recv, int xmit);
|
||||
~WiFiClientSecure_light() override;
|
||||
|
||||
void allocateBuffers(void);
|
||||
|
||||
int connect(IPAddress ip, uint16_t port) override;
|
||||
int connect(const char* name, uint16_t port) override;
|
||||
|
||||
uint8_t connected() override;
|
||||
size_t write(const uint8_t *buf, size_t size) override;
|
||||
size_t write_P(PGM_P buf, size_t size) override;
|
||||
size_t write(const char *buf) {
|
||||
return write((const uint8_t*)buf, strlen(buf));
|
||||
}
|
||||
size_t write_P(const char *buf) {
|
||||
return write_P((PGM_P)buf, strlen_P(buf));
|
||||
}
|
||||
size_t write(Stream& stream); // Note this is not virtual
|
||||
int read(uint8_t *buf, size_t size) override;
|
||||
int available() override;
|
||||
int read() override;
|
||||
int peek() override;
|
||||
size_t peekBytes(uint8_t *buffer, size_t length) override;
|
||||
bool flush(unsigned int maxWaitMs);
|
||||
bool stop(unsigned int maxWaitMs);
|
||||
void flush() override { (void)flush(0); }
|
||||
void stop() override { (void)stop(0); }
|
||||
|
||||
// Only check SHA1 fingerprint of public key
|
||||
void setPubKeyFingerprint(const uint8_t *f1, const uint8_t *f2,
|
||||
bool f_any = false) {
|
||||
_fingerprint1 = f1;
|
||||
_fingerprint2 = f2;
|
||||
_fingerprint_any = f_any;
|
||||
}
|
||||
const uint8_t * getRecvPubKeyFingerprint(void) {
|
||||
return _recv_fingerprint;
|
||||
}
|
||||
|
||||
void setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk,
|
||||
unsigned allowed_usages, unsigned cert_issuer_key_type);
|
||||
|
||||
void setTrustAnchor(const br_x509_trust_anchor *ta);
|
||||
|
||||
// Sets the requested buffer size for transmit and receive
|
||||
void setBufferSizes(int recv, int xmit);
|
||||
|
||||
// Returns whether MFLN negotiation for the above buffer sizes succeeded (after connection)
|
||||
int getMFLNStatus() {
|
||||
return connected() && br_ssl_engine_get_mfln_negotiated(_eng);
|
||||
}
|
||||
|
||||
int32_t getLastError(void) {
|
||||
if (_last_error) {
|
||||
return _last_error;
|
||||
} else {
|
||||
return br_ssl_engine_last_error(_eng);
|
||||
}
|
||||
}
|
||||
inline void setLastError(int32_t err) {
|
||||
_last_error = err;
|
||||
}
|
||||
inline void clearLastError(void) {
|
||||
_last_error = 0;
|
||||
}
|
||||
inline size_t getMaxThunkStackUse(void) {
|
||||
return _max_thunkstack_use;
|
||||
}
|
||||
|
||||
private:
|
||||
void _clear();
|
||||
bool _ctx_present;
|
||||
std::shared_ptr<br_ssl_client_context> _sc;
|
||||
inline bool ctx_present() {
|
||||
return _ctx_present;
|
||||
}
|
||||
br_ssl_engine_context *_eng; // &_sc->eng, to allow for client or server contexts
|
||||
std::shared_ptr<unsigned char> _iobuf_in;
|
||||
std::shared_ptr<unsigned char> _iobuf_out;
|
||||
time_t _now;
|
||||
int _iobuf_in_size;
|
||||
int _iobuf_out_size;
|
||||
bool _handshake_done;
|
||||
uint64_t _last_error;
|
||||
|
||||
bool _fingerprint_any; // accept all fingerprints
|
||||
const uint8_t *_fingerprint1; // fingerprint1 to be checked against
|
||||
const uint8_t *_fingerprint2; // fingerprint2 to be checked against
|
||||
uint8_t _recv_fingerprint[20]; // fingerprint received
|
||||
|
||||
unsigned char *_recvapp_buf;
|
||||
size_t _recvapp_len;
|
||||
|
||||
bool _clientConnected(); // Is the underlying socket alive?
|
||||
bool _connectSSL(const char *hostName); // Do initial SSL handshake
|
||||
void _freeSSL();
|
||||
int _run_until(unsigned target, bool blocking = true);
|
||||
size_t _write(const uint8_t *buf, size_t size, bool pmem);
|
||||
bool _wait_for_handshake(); // Sets and return the _handshake_done after connecting
|
||||
|
||||
// Optional client certificate
|
||||
const br_x509_certificate *_chain_P; // PROGMEM certificate
|
||||
const br_ec_private_key *_sk_ec_P; // PROGMEM private key
|
||||
const br_x509_trust_anchor *_ta_P; // PROGMEM server CA
|
||||
unsigned _allowed_usages;
|
||||
unsigned _cert_issuer_key_type;
|
||||
|
||||
// record the maximum use of ThunkStack for monitoring
|
||||
size_t _max_thunkstack_use;
|
||||
|
||||
};
|
||||
|
||||
#define ERR_OOM -1000
|
||||
#define ERR_CANT_RESOLVE_IP -1001
|
||||
#define ERR_TCP_CONNECT -1002
|
||||
#define ERR_MISSING_EC_KEY -1003
|
||||
#define ERR_MISSING_CA -1004
|
||||
|
||||
// For reference, BearSSL error codes:
|
||||
// #define BR_ERR_OK 0
|
||||
// #define BR_ERR_BAD_PARAM 1
|
||||
// #define BR_ERR_BAD_STATE 2
|
||||
// #define BR_ERR_UNSUPPORTED_VERSION 3
|
||||
// #define BR_ERR_BAD_VERSION 4
|
||||
// #define BR_ERR_BAD_LENGTH 5
|
||||
// #define BR_ERR_TOO_LARGE 6
|
||||
// #define BR_ERR_BAD_MAC 7
|
||||
// #define BR_ERR_NO_RANDOM 8
|
||||
// #define BR_ERR_UNKNOWN_TYPE 9
|
||||
// #define BR_ERR_UNEXPECTED 10
|
||||
// #define BR_ERR_BAD_CCS 12
|
||||
// #define BR_ERR_BAD_ALERT 13
|
||||
// #define BR_ERR_BAD_HANDSHAKE 14
|
||||
// #define BR_ERR_OVERSIZED_ID 15
|
||||
// #define BR_ERR_BAD_CIPHER_SUITE 16
|
||||
// #define BR_ERR_BAD_COMPRESSION 17
|
||||
// #define BR_ERR_BAD_FRAGLEN 18
|
||||
// #define BR_ERR_BAD_SECRENEG 19
|
||||
// #define BR_ERR_EXTRA_EXTENSION 20
|
||||
// #define BR_ERR_BAD_SNI 21
|
||||
// #define BR_ERR_BAD_HELLO_DONE 22
|
||||
// #define BR_ERR_LIMIT_EXCEEDED 23
|
||||
// #define BR_ERR_BAD_FINISHED 24
|
||||
// #define BR_ERR_RESUME_MISMATCH 25
|
||||
// #define BR_ERR_INVALID_ALGORITHM 26
|
||||
// #define BR_ERR_BAD_SIGNATURE 27
|
||||
// #define BR_ERR_WRONG_KEY_USAGE 28
|
||||
// #define BR_ERR_NO_CLIENT_AUTH 29
|
||||
// #define BR_ERR_IO 31
|
||||
// #define BR_ERR_RECV_FATAL_ALERT 256
|
||||
// #define BR_ERR_SEND_FATAL_ALERT 512
|
||||
// #define BR_ERR_X509_OK 32
|
||||
// #define BR_ERR_X509_INVALID_VALUE 33
|
||||
// #define BR_ERR_X509_TRUNCATED 34
|
||||
// #define BR_ERR_X509_EMPTY_CHAIN 35
|
||||
// #define BR_ERR_X509_INNER_TRUNC 36
|
||||
// #define BR_ERR_X509_BAD_TAG_CLASS 37
|
||||
// #define BR_ERR_X509_BAD_TAG_VALUE 38
|
||||
// #define BR_ERR_X509_INDEFINITE_LENGTH 39
|
||||
// #define BR_ERR_X509_EXTRA_ELEMENT 40
|
||||
// #define BR_ERR_X509_UNEXPECTED 41
|
||||
// #define BR_ERR_X509_NOT_CONSTRUCTED 42
|
||||
// #define BR_ERR_X509_NOT_PRIMITIVE 43
|
||||
// #define BR_ERR_X509_PARTIAL_BYTE 44
|
||||
// #define BR_ERR_X509_BAD_BOOLEAN 45
|
||||
// #define BR_ERR_X509_OVERFLOW 46
|
||||
// #define BR_ERR_X509_BAD_DN 47
|
||||
// #define BR_ERR_X509_BAD_TIME 48
|
||||
// #define BR_ERR_X509_UNSUPPORTED 49
|
||||
// #define BR_ERR_X509_LIMIT_EXCEEDED 50
|
||||
// #define BR_ERR_X509_WRONG_KEY_TYPE 51
|
||||
// #define BR_ERR_X509_BAD_SIGNATURE 52
|
||||
// #define BR_ERR_X509_TIME_UNKNOWN 53
|
||||
// #define BR_ERR_X509_EXPIRED 54
|
||||
// #define BR_ERR_X509_DN_MISMATCH 55
|
||||
// #define BR_ERR_X509_BAD_SERVER_NAME 56
|
||||
// #define BR_ERR_X509_CRITICAL_EXTENSION 57
|
||||
// #define BR_ERR_X509_NOT_CA 58
|
||||
// #define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59
|
||||
// #define BR_ERR_X509_WEAK_PUBLIC_KEY 60
|
||||
// #define BR_ERR_X509_NOT_TRUSTED 62
|
||||
|
||||
};
|
||||
|
||||
#endif // USE_MQTT_TLS
|
||||
#endif // wificlientlightbearssl_h
|
||||
/*
|
||||
WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries
|
||||
- Mostly compatible with Arduino WiFi shield library and standard
|
||||
WiFiClient/ServerSecure (except for certificate handling).
|
||||
|
||||
Copyright (c) 2018 Earle F. Philhower, III
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#include <core_version.h>
|
||||
|
||||
#ifndef wificlientlightbearssl_h
|
||||
#define wificlientlightbearssl_h
|
||||
#ifdef USE_TLS
|
||||
#include <vector>
|
||||
#include "WiFiClient.h"
|
||||
#include <t_bearssl.h>
|
||||
|
||||
namespace BearSSL {
|
||||
|
||||
class WiFiClientSecure_light : public WiFiClient {
|
||||
public:
|
||||
WiFiClientSecure_light(int recv, int xmit);
|
||||
~WiFiClientSecure_light() override;
|
||||
|
||||
void allocateBuffers(void);
|
||||
|
||||
int connect(IPAddress ip, uint16_t port) override;
|
||||
int connect(const char* name, uint16_t port) override;
|
||||
|
||||
uint8_t connected() override;
|
||||
size_t write(const uint8_t *buf, size_t size) override;
|
||||
size_t write_P(PGM_P buf, size_t size) override;
|
||||
size_t write(const char *buf) {
|
||||
return write((const uint8_t*)buf, strlen(buf));
|
||||
}
|
||||
size_t write_P(const char *buf) {
|
||||
return write_P((PGM_P)buf, strlen_P(buf));
|
||||
}
|
||||
size_t write(Stream& stream); // Note this is not virtual
|
||||
int read(uint8_t *buf, size_t size) override;
|
||||
int available() override;
|
||||
int read() override;
|
||||
int peek() override;
|
||||
size_t peekBytes(uint8_t *buffer, size_t length) override;
|
||||
bool flush(unsigned int maxWaitMs);
|
||||
bool stop(unsigned int maxWaitMs);
|
||||
void flush() override { (void)flush(0); }
|
||||
void stop() override { (void)stop(0); }
|
||||
|
||||
// Only check SHA1 fingerprint of public key
|
||||
void setPubKeyFingerprint(const uint8_t *f1, const uint8_t *f2,
|
||||
bool f_any = false) {
|
||||
_fingerprint1 = f1;
|
||||
_fingerprint2 = f2;
|
||||
_fingerprint_any = f_any;
|
||||
}
|
||||
const uint8_t * getRecvPubKeyFingerprint(void) {
|
||||
return _recv_fingerprint;
|
||||
}
|
||||
|
||||
void setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk,
|
||||
unsigned allowed_usages, unsigned cert_issuer_key_type);
|
||||
|
||||
void setTrustAnchor(const br_x509_trust_anchor *ta);
|
||||
|
||||
// Sets the requested buffer size for transmit and receive
|
||||
void setBufferSizes(int recv, int xmit);
|
||||
|
||||
// Returns whether MFLN negotiation for the above buffer sizes succeeded (after connection)
|
||||
int getMFLNStatus() {
|
||||
return connected() && br_ssl_engine_get_mfln_negotiated(_eng);
|
||||
}
|
||||
|
||||
int32_t getLastError(void) {
|
||||
if (_last_error) {
|
||||
return _last_error;
|
||||
} else {
|
||||
return br_ssl_engine_last_error(_eng);
|
||||
}
|
||||
}
|
||||
inline void setLastError(int32_t err) {
|
||||
_last_error = err;
|
||||
}
|
||||
inline void clearLastError(void) {
|
||||
_last_error = 0;
|
||||
}
|
||||
inline size_t getMaxThunkStackUse(void) {
|
||||
return _max_thunkstack_use;
|
||||
}
|
||||
|
||||
private:
|
||||
void _clear();
|
||||
bool _ctx_present;
|
||||
std::shared_ptr<br_ssl_client_context> _sc;
|
||||
inline bool ctx_present() {
|
||||
return _ctx_present;
|
||||
}
|
||||
br_ssl_engine_context *_eng; // &_sc->eng, to allow for client or server contexts
|
||||
std::shared_ptr<unsigned char> _iobuf_in;
|
||||
std::shared_ptr<unsigned char> _iobuf_out;
|
||||
time_t _now;
|
||||
int _iobuf_in_size;
|
||||
int _iobuf_out_size;
|
||||
bool _handshake_done;
|
||||
uint64_t _last_error;
|
||||
|
||||
bool _fingerprint_any; // accept all fingerprints
|
||||
const uint8_t *_fingerprint1; // fingerprint1 to be checked against
|
||||
const uint8_t *_fingerprint2; // fingerprint2 to be checked against
|
||||
uint8_t _recv_fingerprint[20]; // fingerprint received
|
||||
|
||||
unsigned char *_recvapp_buf;
|
||||
size_t _recvapp_len;
|
||||
|
||||
bool _clientConnected(); // Is the underlying socket alive?
|
||||
bool _connectSSL(const char *hostName); // Do initial SSL handshake
|
||||
void _freeSSL();
|
||||
int _run_until(unsigned target, bool blocking = true);
|
||||
size_t _write(const uint8_t *buf, size_t size, bool pmem);
|
||||
bool _wait_for_handshake(); // Sets and return the _handshake_done after connecting
|
||||
|
||||
// Optional client certificate
|
||||
const br_x509_certificate *_chain_P; // PROGMEM certificate
|
||||
const br_ec_private_key *_sk_ec_P; // PROGMEM private key
|
||||
const br_x509_trust_anchor *_ta_P; // PROGMEM server CA
|
||||
unsigned _allowed_usages;
|
||||
unsigned _cert_issuer_key_type;
|
||||
|
||||
// record the maximum use of ThunkStack for monitoring
|
||||
size_t _max_thunkstack_use;
|
||||
|
||||
};
|
||||
|
||||
#define ERR_OOM -1000
|
||||
#define ERR_CANT_RESOLVE_IP -1001
|
||||
#define ERR_TCP_CONNECT -1002
|
||||
// #define ERR_MISSING_EC_KEY -1003 // deprecated, AWS IoT is not called if the private key is not present
|
||||
#define ERR_MISSING_CA -1004
|
||||
|
||||
// For reference, BearSSL error codes:
|
||||
// #define BR_ERR_OK 0
|
||||
// #define BR_ERR_BAD_PARAM 1
|
||||
// #define BR_ERR_BAD_STATE 2
|
||||
// #define BR_ERR_UNSUPPORTED_VERSION 3
|
||||
// #define BR_ERR_BAD_VERSION 4
|
||||
// #define BR_ERR_BAD_LENGTH 5
|
||||
// #define BR_ERR_TOO_LARGE 6
|
||||
// #define BR_ERR_BAD_MAC 7
|
||||
// #define BR_ERR_NO_RANDOM 8
|
||||
// #define BR_ERR_UNKNOWN_TYPE 9
|
||||
// #define BR_ERR_UNEXPECTED 10
|
||||
// #define BR_ERR_BAD_CCS 12
|
||||
// #define BR_ERR_BAD_ALERT 13
|
||||
// #define BR_ERR_BAD_HANDSHAKE 14
|
||||
// #define BR_ERR_OVERSIZED_ID 15
|
||||
// #define BR_ERR_BAD_CIPHER_SUITE 16
|
||||
// #define BR_ERR_BAD_COMPRESSION 17
|
||||
// #define BR_ERR_BAD_FRAGLEN 18
|
||||
// #define BR_ERR_BAD_SECRENEG 19
|
||||
// #define BR_ERR_EXTRA_EXTENSION 20
|
||||
// #define BR_ERR_BAD_SNI 21
|
||||
// #define BR_ERR_BAD_HELLO_DONE 22
|
||||
// #define BR_ERR_LIMIT_EXCEEDED 23
|
||||
// #define BR_ERR_BAD_FINISHED 24
|
||||
// #define BR_ERR_RESUME_MISMATCH 25
|
||||
// #define BR_ERR_INVALID_ALGORITHM 26
|
||||
// #define BR_ERR_BAD_SIGNATURE 27
|
||||
// #define BR_ERR_WRONG_KEY_USAGE 28
|
||||
// #define BR_ERR_NO_CLIENT_AUTH 29
|
||||
// #define BR_ERR_IO 31
|
||||
// #define BR_ERR_RECV_FATAL_ALERT 256
|
||||
// #define BR_ERR_SEND_FATAL_ALERT 512
|
||||
// #define BR_ERR_X509_OK 32
|
||||
// #define BR_ERR_X509_INVALID_VALUE 33
|
||||
// #define BR_ERR_X509_TRUNCATED 34
|
||||
// #define BR_ERR_X509_EMPTY_CHAIN 35
|
||||
// #define BR_ERR_X509_INNER_TRUNC 36
|
||||
// #define BR_ERR_X509_BAD_TAG_CLASS 37
|
||||
// #define BR_ERR_X509_BAD_TAG_VALUE 38
|
||||
// #define BR_ERR_X509_INDEFINITE_LENGTH 39
|
||||
// #define BR_ERR_X509_EXTRA_ELEMENT 40
|
||||
// #define BR_ERR_X509_UNEXPECTED 41
|
||||
// #define BR_ERR_X509_NOT_CONSTRUCTED 42
|
||||
// #define BR_ERR_X509_NOT_PRIMITIVE 43
|
||||
// #define BR_ERR_X509_PARTIAL_BYTE 44
|
||||
// #define BR_ERR_X509_BAD_BOOLEAN 45
|
||||
// #define BR_ERR_X509_OVERFLOW 46
|
||||
// #define BR_ERR_X509_BAD_DN 47
|
||||
// #define BR_ERR_X509_BAD_TIME 48
|
||||
// #define BR_ERR_X509_UNSUPPORTED 49
|
||||
// #define BR_ERR_X509_LIMIT_EXCEEDED 50
|
||||
// #define BR_ERR_X509_WRONG_KEY_TYPE 51
|
||||
// #define BR_ERR_X509_BAD_SIGNATURE 52
|
||||
// #define BR_ERR_X509_TIME_UNKNOWN 53
|
||||
// #define BR_ERR_X509_EXPIRED 54
|
||||
// #define BR_ERR_X509_DN_MISMATCH 55
|
||||
// #define BR_ERR_X509_BAD_SERVER_NAME 56
|
||||
// #define BR_ERR_X509_CRITICAL_EXTENSION 57
|
||||
// #define BR_ERR_X509_NOT_CA 58
|
||||
// #define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59
|
||||
// #define BR_ERR_X509_WEAK_PUBLIC_KEY 60
|
||||
// #define BR_ERR_X509_NOT_TRUSTED 62
|
||||
|
||||
};
|
||||
|
||||
#endif // USE_TLS
|
||||
#endif // wificlientlightbearssl_h
|
||||
|
|
|
@ -271,6 +271,8 @@
|
|||
#define D_CMND_SSID "SSId"
|
||||
#define D_CMND_PASSWORD "Password"
|
||||
#define D_CMND_HOSTNAME "Hostname"
|
||||
#define D_CMND_WIFI "Wifi"
|
||||
#define D_CMND_ETHERNET "Ethernet"
|
||||
#define D_CMND_WIFICONFIG "WifiConfig"
|
||||
#define D_WCFG_0_RESTART "Restart"
|
||||
#define D_WCFG_2_WIFIMANAGER "WifiManager"
|
||||
|
@ -503,10 +505,14 @@
|
|||
#define D_CMND_ZIGBEE_RESET "Reset"
|
||||
#define D_JSON_ZIGBEE_CC2530 "CC2530"
|
||||
#define D_CMND_ZIGBEEZNPRECEIVE "ZNPReceive" // only for debug
|
||||
#define D_CMND_ZIGBEE_EZSP_RECEIVE "EZSPReceive" // only for debug
|
||||
#define D_CMND_ZIGBEEZNPSEND "ZNPSend"
|
||||
#define D_CMND_ZIGBEE_EZSP_SEND "EZSPSend"
|
||||
#define D_JSON_ZIGBEE_STATE "ZbState"
|
||||
#define D_JSON_ZIGBEEZNPRECEIVED "ZbZNPReceived"
|
||||
#define D_JSON_ZIGBEE_EZSP_RECEIVED "ZbEZSPReceived"
|
||||
#define D_JSON_ZIGBEEZNPSENT "ZbZNPSent"
|
||||
#define D_JSON_ZIGBEE_EZSP_SENT "ZbEZSPSent"
|
||||
#define D_JSON_ZIGBEEZCL_RECEIVED "ZbZCLReceived"
|
||||
#define D_JSON_ZIGBEEZCL_RAW_RECEIVED "ZbZCLRawReceived"
|
||||
#define D_JSON_ZIGBEE_DEVICE "Device"
|
||||
|
@ -641,6 +647,7 @@
|
|||
#define D_LOG_UPNP "UPP: " // UPnP
|
||||
#define D_LOG_WIFI "WIF: " // Wifi
|
||||
#define D_LOG_ZIGBEE "ZIG: " // Zigbee
|
||||
#define D_LOG_TCP "TCP: " // TCP bridge
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Подобрена комуникация"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Използвана енергия днес"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Communication Enhancement"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Spotřeba Dnes"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Erweiterte Kommunikation"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energie heute"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Βελτίωση επικοινωνίας"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Ενέργεια σήμερα"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Communication Enhancement"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energy Today"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Mejora de Comunicación"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX ESCENA TX"
|
||||
#define D_KNX_RX_SCENE "KNX ESCENA RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energía Hoy"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Amélioration de la communication"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX Scène TX"
|
||||
#define D_KNX_RX_SCENE "KNX Scène RX"
|
||||
|
||||
// xsns_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Énergie aujourd'hui"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "Hibernation"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Esclave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Esclave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Esclave Rst"
|
||||
#define D_SENSOR_CLIENT_TX "Esclave TX"
|
||||
#define D_SENSOR_CLIENT_RX "Esclave RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Esclave Rst"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "שיפור התקשורת"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "צריכה יומית"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Communication Enhancement"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Mai energia"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Miglioramento comunicazione"
|
||||
#define D_KNX_TX_SLOT "KNX - TX"
|
||||
#define D_KNX_RX_SLOT "KNX - RX"
|
||||
#define D_KNX_TX_SCENE "Scena - TX"
|
||||
#define D_KNX_RX_SCENE "Scena - RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energia - oggi"
|
||||
|
@ -663,16 +665,16 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 - DATI"
|
||||
#define D_SENSOR_DEEPSLEEP "Deep sleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS - Abilita"
|
||||
#define D_SENSOR_SLAVE_TX "Slave - TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave - RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave - RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client - TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client - RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client - RST"
|
||||
#define D_SENSOR_GPS_RX "GPS - RX"
|
||||
#define D_SENSOR_GPS_TX "GPS - TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 - RX"
|
||||
#define D_SENSOR_HM10_TX "HM10 - TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR - RX"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR - TX"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 - RX"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 - GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 - GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL - RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "Velocità vento"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP - TX"
|
||||
#define D_SENSOR_TCP_RXD "TCP - RX"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "커뮤니케이션 강화"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "금일 전력 사용량"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Verbeter verbinding"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Verbruik vandaag"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Rozszerzenia"
|
||||
#define D_KNX_TX_SLOT "Gniazdo TX"
|
||||
#define D_KNX_RX_SLOT "Gniazdo RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energia dzisiaj"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "Głęboko uśpiony"
|
||||
#define D_SENSOR_EXS_ENABLE "Załącz EXS"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Melhoria da comunicação"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Consumo energético de hoje"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Melhoria de Comunicação"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Consumo energético de hoje"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Îmbunătățire Communicație"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energia de Azi"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Communication Enhancement"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Энергия Сегодня"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "А"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Communication Enhancement"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Spotreba dnes"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Kommuniceringsförbättring"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energi idag"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Communication Enhancement"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energy Today"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Підвищення зв'язку"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Енергія Сьогодні"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "А"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "通讯增强"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "今日用电量"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "安"
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define D_KNX_ENHANCEMENT "Communication Enhancement"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
#define D_KNX_TX_SCENE "KNX SCENE TX"
|
||||
#define D_KNX_RX_SCENE "KNX SCENE RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "今日用電量"
|
||||
|
@ -663,9 +665,9 @@
|
|||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
#define D_SENSOR_CLIENT_TX "Client TX"
|
||||
#define D_SENSOR_CLIENT_RX "Client RX"
|
||||
#define D_SENSOR_CLIENT_RESET "Client RST"
|
||||
#define D_SENSOR_GPS_RX "GPS RX"
|
||||
#define D_SENSOR_GPS_TX "GPS TX"
|
||||
#define D_SENSOR_HM10_RX "HM10 RX"
|
||||
|
@ -681,6 +683,7 @@
|
|||
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
|
||||
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
|
||||
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
|
||||
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
|
||||
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
|
||||
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
|
||||
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
|
||||
|
@ -693,6 +696,11 @@
|
|||
#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
|
||||
#define D_GPIO_WEBCAM_HSD "CAM_HSD"
|
||||
#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
|
||||
#define D_SENSOR_ETH_PHY_POWER "ETH POWER"
|
||||
#define D_SENSOR_ETH_PHY_MDC "ETH MDC"
|
||||
#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO"
|
||||
#define D_SENSOR_TCP_TXD "TCP Tx"
|
||||
#define D_SENSOR_TCP_RXD "TCP Rx"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "安"
|
||||
|
|
|
@ -50,7 +50,12 @@
|
|||
#define PROJECT "tasmota" // PROJECT is used as the default topic delimiter
|
||||
|
||||
// If not selected the default will be SONOFF_BASIC
|
||||
//#define MODULE SONOFF_BASIC // [Module] Select default model from tasmota_template.h
|
||||
//#define MODULE SONOFF_BASIC // [Module] Select default module from tasmota_template.h
|
||||
#ifdef ESP8266
|
||||
#define FALLBACK_MODULE SONOFF_BASIC // [Module2] Select default module on fast reboot where USER_MODULE is user template
|
||||
#else // ESP32
|
||||
#define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template
|
||||
#endif
|
||||
|
||||
#define SAVE_DATA 1 // [SaveData] Save changed parameters to Flash (0 = disable, 1 - 3600 seconds)
|
||||
#define SAVE_STATE true // [SetOption0] Save changed power state to Flash (false = disable, true = enable)
|
||||
|
@ -135,6 +140,8 @@
|
|||
// -- MQTT - Home Assistant Discovery -------------
|
||||
#define HOME_ASSISTANT_DISCOVERY_ENABLE false // [SetOption19] Home Assistant Discovery (false = Disable, true = Enable)
|
||||
#define HASS_AS_LIGHT false // [SetOption30] Enforce HAss autodiscovery as light
|
||||
//#define DEEPSLEEP_LWT_HA_DISCOVERY // Enable LWT topic and its payloads for read-only sensors (Status sensor not included) and binary_sensors on HAss Discovery (Commented out: all read-only sensors and binary_sensors
|
||||
// won't be shown as OFFLINE on Home Assistant when the device is DeepSleeping - NOTE: This is only for read-only sensors and binary_sensors, relays will be shown as OFFLINE)
|
||||
|
||||
// -- MQTT - Options ------------------------------
|
||||
#define MQTT_RESULT_COMMAND false // [SetOption4] Switch between MQTT RESULT or COMMAND
|
||||
|
@ -367,6 +374,11 @@
|
|||
// Full documentation here: https://github.com/arendst/Tasmota/wiki/AWS-IoT
|
||||
// #define USE_4K_RSA // Support 4096 bits certificates, instead of 2048
|
||||
|
||||
// -- Telegram Protocol ---------------------------
|
||||
//#define USE_TELEGRAM // Support for Telegram protocol (+49k code, +7.0k mem and +4.8k additional during connection handshake)
|
||||
#define USE_TELEGRAM_FINGERPRINT "\xB2\x72\x47\xA6\x69\x8C\x3C\x69\xF9\x58\x6C\xF3\x60\x02\xFB\x83\xFA\x8B\x1F\x23" // Telegram api.telegram.org TLS public key fingerpring
|
||||
// #define USE_MQTT_TLS_CA_CERT // Use certificate instead of fingerprint
|
||||
|
||||
// -- KNX IP Protocol -----------------------------
|
||||
//#define USE_KNX // Enable KNX IP Protocol Support (+9.4k code, +3k7 mem)
|
||||
#define USE_KNX_WEB_MENU // Enable KNX WEB MENU (+8.3k code, +144 mem)
|
||||
|
@ -522,6 +534,7 @@
|
|||
// #define USE_VEML6075 // [I2cDriver49] Enable VEML6075 UVA/UVB/UVINDEX Sensor (I2C address 0x10) (+2k1 code)
|
||||
// #define USE_VEML7700 // [I2cDriver50] Enable VEML7700 Ambient Light sensor (I2C addresses 0x10) (+4k5 code)
|
||||
// #define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code)
|
||||
// #define USE_HP303B // [I2cDriver52] Enable HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code)
|
||||
|
||||
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
|
||||
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
|
||||
|
@ -571,6 +584,7 @@
|
|||
#define STARTING_OFFSET 30 // Turn on NovaSDS XX-seconds before tele_period is reached
|
||||
//#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor (+1k4)
|
||||
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
|
||||
//#define USE_TCP_BRIDGE // Add support for Serial to TCP bridge (+1.3k code)
|
||||
//#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
|
||||
#define MP3_VOLUME 10 // Set the startup volume on init, the range can be 0..30(max)
|
||||
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
|
||||
|
@ -583,14 +597,11 @@
|
|||
//#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM)
|
||||
// #define USE_FLOG // Add support for GPS logging in OTA's Flash (Experimental) (+2k9 code, +8 bytes RAM)
|
||||
//#define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge (+9k3 code)
|
||||
//#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
|
||||
//#define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
|
||||
//#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k6 code, 64 mem)
|
||||
#define USE_TASMOTA_SLAVE_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants
|
||||
#define USE_TASMOTA_SLAVE_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini
|
||||
//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k6 code, 64 mem)
|
||||
#define USE_TASMOTA_CLIENT_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants
|
||||
#define USE_TASMOTA_CLIENT_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini
|
||||
//#define USE_OPENTHERM // Add support for OpenTherm (+15k code)
|
||||
#define USE_TELEINFO // Add support for Teleinfo via serial RX interface
|
||||
//#define USE_TELEINFO_STANDARD // Use standard mode (9600 bps) else it's historical mode (1200 bps)
|
||||
|
||||
// -- Power monitoring sensors --------------------
|
||||
#define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code)
|
||||
|
@ -614,6 +625,8 @@
|
|||
#define LE01MR_SPEED 9600 // LE-01MR modbus baudrate (default: 9600)
|
||||
#define LE01MR_ADDR 1 // LE-01MR modbus address (default: 0x01)
|
||||
#define USE_BL0940 // Add support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code)
|
||||
//#define USE_TELEINFO // Add support for Teleinfo via serial RX interface (+5k2 code, +168 RAM + SmartMeter LinkedList Values RAM)
|
||||
// #define USE_TELEINFO_STANDARD // Use standard mode (9600 bps) else it's historical mode (1200 bps)
|
||||
|
||||
// -- Low level interface devices -----------------
|
||||
#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code)
|
||||
|
@ -624,6 +637,7 @@
|
|||
#define MAX31865_PTD_RES 100 // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!)
|
||||
#define MAX31865_REF_RES 430 // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000)
|
||||
#define MAX31865_PTD_BIAS 0 // To calibrate your not-so-good PTD
|
||||
//#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code)
|
||||
|
||||
// -- IR Remote features - all protocols from IRremoteESP8266 --------------------------
|
||||
// IR Full Protocols mode is activated through platform.io only.
|
||||
|
@ -648,6 +662,9 @@
|
|||
|
||||
// -- Zigbee interface ----------------------------
|
||||
//#define USE_ZIGBEE // Enable serial communication with Zigbee CC2530 flashed with ZNP (+49k code, +3k mem)
|
||||
#define USE_ZIGBEE_ZNP // Enable ZNP protocol, needed for CC2530 based devices
|
||||
// #define USE_ZIGBEE_EZSP // [EXPERIMENTAL - DO NOT USE] Enable EZSP protocol, needed for EFR32 EmberZNet based devices, like Sonoff Zigbee bridge
|
||||
// Note: USE_ZIGBEE_ZNP and USE_ZIGBEE_EZSP are mutually incompatible, you must select exactly one
|
||||
#define USE_ZIGBEE_PANID 0x1A63 // arbitrary PAN ID for Zigbee network, must be unique in the home
|
||||
// if PANID == 0xFFFF, then the device will act as a Zigbee router, the parameters below are ignored
|
||||
// if PANID == 0xFFFE, then the device will act as a Zigbee end-device (non-router), the parameters below are ignored
|
||||
|
@ -657,6 +674,8 @@
|
|||
#define USE_ZIGBEE_PRECFGKEY_H 0x0D0C0A0806040200L // note: changing requires to re-pair all devices
|
||||
|
||||
#define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms)
|
||||
#define USE_ZIGBEE_MODELID "Tasmota Z2T" // reported "ModelId" (cluster 0000 / attribute 0005)
|
||||
#define USE_ZIGBEE_MANUFACTURER "Tasmota" // reported "Manufacturer" (cluster 0000 / attribute 0004)
|
||||
|
||||
// -- Other sensors/drivers -----------------------
|
||||
|
||||
|
@ -716,6 +735,28 @@
|
|||
|
||||
// -- End of general directives -------------------
|
||||
|
||||
/*********************************************************************************************\
|
||||
* ESP32 only features
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifdef ESP32
|
||||
|
||||
//#define USE_ETHERNET // Add support for ethernet (Currently fixed for Olimex ESP32-PoE)
|
||||
// Olimex ESP32-PoE
|
||||
#define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101
|
||||
#define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31
|
||||
#define ETH_CLKMODE 3 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT
|
||||
// wESP32-PoE
|
||||
// #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101
|
||||
// #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31
|
||||
// #define ETH_CLKMODE 0 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT
|
||||
|
||||
//#define USE_SPI // Add support for hardware SPI
|
||||
//#define USE_MI_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
|
||||
//#define USE_WEBCAM // Add support for webcam
|
||||
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Debug features
|
||||
\*********************************************************************************************/
|
||||
|
@ -755,4 +796,16 @@
|
|||
#error "Select either USE_RULES or USE_SCRIPT. They can't both be used at the same time"
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Post-process compile options for TLS
|
||||
\*********************************************************************************************/
|
||||
|
||||
#if defined(USE_MQTT_TLS) || defined(USE_SENDMAIL) || defined(USE_TELEGRAM)
|
||||
#define USE_TLS // flag indicates we need to include TLS code
|
||||
|
||||
#if defined(USE_MQTT_AWS_IOT) || defined(USE_TELEGRAM)
|
||||
#define USE_MQTT_TLS_FORCE_EC_CIPHER // AWS IoT and TELEGRAM require EC Cipher
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // _MY_USER_CONFIG_H_
|
||||
|
|
|
@ -114,8 +114,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||
uint32_t pwm_ct_mode : 1; // bit 10 (v8.2.0.4) - SetOption92 - Set PWM Mode from regular PWM to ColorTemp control (Xiaomi Philips ...)
|
||||
uint32_t compress_rules_cpu : 1; // bit 11 (v8.2.0.6) - SetOption93 - Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick
|
||||
uint32_t max6675 : 1; // bit 12 (v8.3.1.2) - SetOption94 - Implement simpler MAX6675 protocol instead of MAX31855
|
||||
uint32_t spare13 : 1;
|
||||
uint32_t spare14 : 1;
|
||||
uint32_t network_wifi : 1; // bit 13 (v8.3.1.3) - CMND_WIFI
|
||||
uint32_t network_ethernet : 1; // bit 14 (v8.3.1.3) = CMND_ETHERNET
|
||||
uint32_t spare15 : 1;
|
||||
uint32_t spare16 : 1;
|
||||
uint32_t spare17 : 1;
|
||||
|
@ -392,12 +392,13 @@ struct {
|
|||
#else // ESP32
|
||||
myio my_gp; // 3AC - 2 x 40 bytes (ESP32)
|
||||
mytmplt user_template; // 3FC - 2 x 37 bytes (ESP32)
|
||||
uint8_t eth_type; // 446
|
||||
uint8_t eth_clk_mode; // 447
|
||||
|
||||
uint8_t free_esp32_446[6]; // 446
|
||||
uint8_t free_esp32_448[4]; // 448
|
||||
|
||||
WebCamCfg webcam_config; // 44C
|
||||
|
||||
uint8_t free_esp32_450[1]; // 450
|
||||
uint8_t eth_address; // 450
|
||||
#endif // ESP8266 - ESP32
|
||||
|
||||
char serial_delimiter; // 451
|
||||
|
@ -566,10 +567,12 @@ struct {
|
|||
uint16_t windmeter_pulse_debounce; // F3A
|
||||
int16_t windmeter_speed_factor; // F3C
|
||||
uint8_t windmeter_tele_pchange; // F3E
|
||||
uint8_t ledpwm_on; // F3F
|
||||
uint8_t ledpwm_off; // F40
|
||||
uint8_t ledpwm_on; // F3F
|
||||
uint8_t ledpwm_off; // F40
|
||||
uint8_t tcp_baudrate; // F41
|
||||
uint8_t fallback_module; // F42
|
||||
|
||||
uint8_t free_f42[119]; // F41 - Decrement if adding new Setting variables just above and below
|
||||
uint8_t free_f43[117]; // F43 - Decrement if adding new Setting variables just above and below
|
||||
|
||||
// Only 32 bit boundary variables below
|
||||
uint16_t pulse_counter_debounce_low; // FB8
|
||||
|
@ -647,13 +650,14 @@ struct XDRVMAILBOX {
|
|||
} XdrvMailbox;
|
||||
|
||||
#ifdef USE_SHUTTER
|
||||
const uint8_t MAX_RULES_FLAG = 10; // Number of bits used in RulesBitfield (tricky I know...)
|
||||
const uint8_t MAX_RULES_FLAG = 11; // Number of bits used in RulesBitfield (tricky I know...)
|
||||
#else
|
||||
const uint8_t MAX_RULES_FLAG = 8; // Number of bits used in RulesBitfield (tricky I know...)
|
||||
const uint8_t MAX_RULES_FLAG = 9; // Number of bits used in RulesBitfield (tricky I know...)
|
||||
#endif // USE_SHUTTER
|
||||
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
|
||||
uint16_t data; // Allow bit manipulation
|
||||
struct {
|
||||
uint16_t system_init : 1; // Changing layout here needs adjustments in xdrv_10_rules.ino too
|
||||
uint16_t system_boot : 1;
|
||||
uint16_t time_init : 1;
|
||||
uint16_t time_set : 1;
|
||||
|
@ -664,7 +668,6 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||
uint16_t http_init : 1;
|
||||
uint16_t shutter_moved : 1;
|
||||
uint16_t shutter_moving : 1;
|
||||
uint16_t spare10 : 1;
|
||||
uint16_t spare11 : 1;
|
||||
uint16_t spare12 : 1;
|
||||
uint16_t spare13 : 1;
|
||||
|
@ -676,10 +679,10 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||
typedef union {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t wifi_down : 1;
|
||||
uint8_t network_down : 1;
|
||||
uint8_t mqtt_down : 1;
|
||||
uint8_t spare02 : 1;
|
||||
uint8_t spare03 : 1;
|
||||
uint8_t wifi_down : 1;
|
||||
uint8_t eth_down : 1;
|
||||
uint8_t spare04 : 1;
|
||||
uint8_t spare05 : 1;
|
||||
uint8_t spare06 : 1;
|
||||
|
|
|
@ -768,6 +768,7 @@ void SettingsDefaultSet2(void)
|
|||
// flag.interlock |= 0;
|
||||
Settings.interlock[0] = 0xFF; // Legacy support using all relays in one interlock group
|
||||
Settings.module = MODULE;
|
||||
Settings.fallback_module = FALLBACK_MODULE;
|
||||
ModuleDefault(WEMOS);
|
||||
// for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; }
|
||||
SettingsUpdateText(SET_FRIENDLYNAME1, PSTR(FRIENDLY_NAME));
|
||||
|
@ -798,7 +799,16 @@ void SettingsDefaultSet2(void)
|
|||
Settings.serial_delimiter = 0xff;
|
||||
Settings.seriallog_level = SERIAL_LOG_LEVEL;
|
||||
|
||||
// Ethernet
|
||||
flag4.network_ethernet |= 1;
|
||||
#ifdef ESP32
|
||||
Settings.eth_type = ETH_TYPE;
|
||||
Settings.eth_clk_mode = ETH_CLKMODE;
|
||||
Settings.eth_address = ETH_ADDR;
|
||||
#endif
|
||||
|
||||
// Wifi
|
||||
flag4.network_wifi |= 1;
|
||||
flag3.use_wifi_scan |= WIFI_SCAN_AT_RESTART;
|
||||
flag3.use_wifi_rescan |= WIFI_SCAN_REGULARLY;
|
||||
Settings.wifi_output_power = 170;
|
||||
|
@ -1439,6 +1449,20 @@ void SettingsDelta(void)
|
|||
Settings.ledpwm_on = 255;
|
||||
Settings.ledpwm_mask = 0;
|
||||
}
|
||||
if (Settings.version < 0x08030104) {
|
||||
Settings.flag4.network_wifi = 1;
|
||||
Settings.flag4.network_ethernet = 1;
|
||||
}
|
||||
#ifdef ESP32
|
||||
if (Settings.version < 0x08030105) {
|
||||
Settings.eth_type = ETH_TYPE;
|
||||
Settings.eth_clk_mode = ETH_CLKMODE;
|
||||
Settings.eth_address = ETH_ADDR;
|
||||
}
|
||||
#endif
|
||||
if (Settings.version < 0x08030106) {
|
||||
Settings.fallback_module = FALLBACK_MODULE;
|
||||
}
|
||||
|
||||
Settings.version = VERSION;
|
||||
SettingsSave(1);
|
||||
|
|
|
@ -156,7 +156,7 @@ float CharToFloat(const char *str)
|
|||
|
||||
signed char sign = 1;
|
||||
if (*pt == '-') { sign = -1; }
|
||||
if (*pt == '-' || *pt=='+') { pt++; } // Skip any sign
|
||||
if (*pt == '-' || *pt == '+') { pt++; } // Skip any sign
|
||||
|
||||
float left = 0;
|
||||
if (*pt != '.') {
|
||||
|
@ -167,6 +167,9 @@ float CharToFloat(const char *str)
|
|||
float right = 0;
|
||||
if (*pt == '.') {
|
||||
pt++;
|
||||
uint32_t max_decimals = 0;
|
||||
while ((max_decimals < 8) && isdigit(pt[max_decimals])) { max_decimals++; }
|
||||
pt[max_decimals] = '\0'; // Limit decimals to float max of 8
|
||||
right = atoi(pt); // Decimal part
|
||||
while (isdigit(*pt)) {
|
||||
pt++;
|
||||
|
@ -687,9 +690,9 @@ void ResetGlobalValues(void)
|
|||
{
|
||||
if ((uptime - global_update) > GLOBAL_VALUES_VALID) { // Reset after 5 minutes
|
||||
global_update = 0;
|
||||
global_temperature = 9999;
|
||||
global_humidity = 0;
|
||||
global_pressure = 0;
|
||||
global_temperature = NAN;
|
||||
global_humidity = 0.0f;
|
||||
global_pressure = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -997,7 +1000,7 @@ char* ResponseGetTime(uint32_t format, char* time_str)
|
|||
snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":%u"), UtcTime());
|
||||
break;
|
||||
case 3:
|
||||
snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s.%03d\""), GetDateAndTime(DT_LOCAL).c_str(), RtcMillis());
|
||||
snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL_MILLIS).c_str());
|
||||
break;
|
||||
default:
|
||||
snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str());
|
||||
|
@ -1356,7 +1359,15 @@ bool JsonTemplate(const char* dataBuf)
|
|||
}
|
||||
if (obj[D_JSON_GPIO].success()) {
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) {
|
||||
#ifdef ESP8266
|
||||
Settings.user_template.gp.io[i] = obj[D_JSON_GPIO][i] | 0;
|
||||
#else // ESP32
|
||||
uint16_t gpio = obj[D_JSON_GPIO][i] | 0;
|
||||
if (gpio == (AGPIO(GPIO_NONE) +1)) {
|
||||
gpio = AGPIO(GPIO_USER);
|
||||
}
|
||||
Settings.user_template.gp.io[i] = gpio;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (obj[D_JSON_FLAG].success()) {
|
||||
|
@ -1375,7 +1386,15 @@ void TemplateJson(void)
|
|||
{
|
||||
Response_P(PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), SettingsText(SET_TEMPLATE_NAME));
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) {
|
||||
#ifdef ESP8266
|
||||
ResponseAppend_P(PSTR("%s%d"), (i>0)?",":"", Settings.user_template.gp.io[i]);
|
||||
#else // ESP32
|
||||
uint16_t gpio = Settings.user_template.gp.io[i];
|
||||
if (gpio == AGPIO(GPIO_USER)) {
|
||||
gpio = AGPIO(GPIO_NONE) +1;
|
||||
}
|
||||
ResponseAppend_P(PSTR("%s%d"), (i>0)?",":"", gpio);
|
||||
#endif
|
||||
}
|
||||
ResponseAppend_P(PSTR("],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), Settings.user_template.flag, Settings.user_template_base +1);
|
||||
}
|
||||
|
@ -1601,8 +1620,8 @@ void I2cScan(char *devs, unsigned int devs_len)
|
|||
// Return error codes defined in twi.h and core_esp8266_si2c.c
|
||||
// I2C_OK 0
|
||||
// I2C_SCL_HELD_LOW 1 = SCL held low by another device, no procedure available to recover
|
||||
// I2C_SCL_HELD_LOW_AFTER_READ 2 = I2C bus error. SCL held low beyond slave clock stretch time
|
||||
// I2C_SDA_HELD_LOW 3 = I2C bus error. SDA line held low by slave/another_master after n bits
|
||||
// I2C_SCL_HELD_LOW_AFTER_READ 2 = I2C bus error. SCL held low beyond client clock stretch time
|
||||
// I2C_SDA_HELD_LOW 3 = I2C bus error. SDA line held low by client/another_master after n bits
|
||||
// I2C_SDA_HELD_LOW_AFTER_INIT 4 = line busy. SDA again held low by another device. 2nd master?
|
||||
|
||||
uint8_t error = 0;
|
||||
|
@ -1738,7 +1757,7 @@ void Syslog(void)
|
|||
}
|
||||
if (PortUdp.beginPacket(syslog_host_addr, Settings.syslog_port)) {
|
||||
char syslog_preamble[64]; // Hostname + Id
|
||||
snprintf_P(syslog_preamble, sizeof(syslog_preamble), PSTR("%s ESP-"), my_hostname);
|
||||
snprintf_P(syslog_preamble, sizeof(syslog_preamble), PSTR("%s ESP-"), NetworkHostname());
|
||||
memmove(log_data + strlen(syslog_preamble), log_data, sizeof(log_data) - strlen(syslog_preamble));
|
||||
log_data[sizeof(log_data) -1] = '\0';
|
||||
memcpy(log_data, syslog_preamble, strlen(syslog_preamble));
|
||||
|
@ -1785,7 +1804,7 @@ void AddLog(uint32_t loglevel)
|
|||
!global_state.mqtt_down &&
|
||||
(loglevel <= Settings.mqttlog_level)) { MqttPublishLogging(mxtime); }
|
||||
|
||||
if (!global_state.wifi_down &&
|
||||
if (!global_state.network_down &&
|
||||
(loglevel <= syslog_level)) { Syslog(); }
|
||||
|
||||
prepped_loglevel = 0;
|
||||
|
|
|
@ -27,7 +27,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix
|
|||
D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|"
|
||||
D_CMND_DEVICENAME "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|"
|
||||
D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_LEDPWM_ON "|" D_CMND_LEDPWM_OFF "|" D_CMND_LEDPWM_MODE "|"
|
||||
D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|"
|
||||
D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_WIFI "|"
|
||||
#ifdef USE_I2C
|
||||
D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|"
|
||||
#endif
|
||||
|
@ -54,7 +54,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = {
|
|||
&CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig,
|
||||
&CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd,
|
||||
&CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode,
|
||||
&CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum,
|
||||
&CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndWifi,
|
||||
#ifdef USE_I2C
|
||||
&CmndI2cScan, CmndI2cDriver,
|
||||
#endif
|
||||
|
@ -499,8 +499,8 @@ void CmndStatus(void)
|
|||
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"" D_JSON_GATEWAY "\":\"%s\",\""
|
||||
D_JSON_SUBNETMASK "\":\"%s\",\"" D_JSON_DNSSERVER "\":\"%s\",\"" D_JSON_MAC "\":\"%s\",\""
|
||||
D_CMND_WEBSERVER "\":%d,\"" D_CMND_WIFICONFIG "\":%d,\"" D_CMND_WIFIPOWER "\":%s}}"),
|
||||
my_hostname, WiFi.localIP().toString().c_str(), IPAddress(Settings.ip_address[1]).toString().c_str(),
|
||||
IPAddress(Settings.ip_address[2]).toString().c_str(), IPAddress(Settings.ip_address[3]).toString().c_str(), WiFi.macAddress().c_str(),
|
||||
NetworkHostname(), NetworkAddress().toString().c_str(), IPAddress(Settings.ip_address[1]).toString().c_str(),
|
||||
IPAddress(Settings.ip_address[2]).toString().c_str(), IPAddress(Settings.ip_address[3]).toString().c_str(), NetworkMacAddress().c_str(),
|
||||
Settings.webserver, Settings.sta_config, WifiGetOutputPower().c_str());
|
||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "5"));
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ void CmndGlobalTemp(void)
|
|||
if (!isnan(temperature) && Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit
|
||||
temperature = (temperature - 32) / 1.8; // Celsius
|
||||
}
|
||||
if ((temperature >= -50.0) && (temperature <= 100.0)) {
|
||||
if ((temperature >= -50.0f) && (temperature <= 100.0f)) {
|
||||
ConvertTemp(temperature);
|
||||
global_update = 1; // Keep global values just entered valid
|
||||
}
|
||||
|
@ -1018,18 +1018,29 @@ void CmndModule(void)
|
|||
present = ValidTemplateModule(XdrvMailbox.payload);
|
||||
}
|
||||
if (present) {
|
||||
Settings.last_module = Settings.module;
|
||||
Settings.module = XdrvMailbox.payload;
|
||||
SetModuleType();
|
||||
if (Settings.last_module != XdrvMailbox.payload) {
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) {
|
||||
Settings.my_gp.io[i] = GPIO_NONE;
|
||||
if (XdrvMailbox.index == 2) {
|
||||
Settings.fallback_module = XdrvMailbox.payload;
|
||||
} else {
|
||||
Settings.last_module = Settings.module;
|
||||
Settings.module = XdrvMailbox.payload;
|
||||
SetModuleType();
|
||||
if (Settings.last_module != XdrvMailbox.payload) {
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) {
|
||||
Settings.my_gp.io[i] = GPIO_NONE;
|
||||
}
|
||||
}
|
||||
restart_flag = 2;
|
||||
}
|
||||
restart_flag = 2;
|
||||
}
|
||||
}
|
||||
Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, ModuleNr(), ModuleName().c_str());
|
||||
uint8_t module_real = Settings.module;
|
||||
uint8_t module_number = ModuleNr();
|
||||
if (XdrvMailbox.index == 2) {
|
||||
module_real = Settings.fallback_module;
|
||||
module_number = (USER_MODULE == Settings.fallback_module) ? 0 : Settings.fallback_module +1;
|
||||
strcat(XdrvMailbox.command, "2");
|
||||
}
|
||||
Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, module_number, AnyModuleName(module_real).c_str());
|
||||
}
|
||||
|
||||
void CmndModules(void)
|
||||
|
@ -1497,6 +1508,15 @@ void CmndWifiConfig(void)
|
|||
Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, Settings.sta_config, GetTextIndexed(stemp1, sizeof(stemp1), Settings.sta_config, kWifiConfig));
|
||||
}
|
||||
|
||||
void CmndWifi(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
|
||||
Settings.flag4.network_wifi = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
}
|
||||
ResponseCmndStateText(Settings.flag4.network_wifi);
|
||||
}
|
||||
|
||||
void CmndDevicename(void)
|
||||
{
|
||||
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) {
|
||||
|
|
|
@ -477,8 +477,8 @@ void GetFeatures(void)
|
|||
#ifdef USE_EXS_DIMMER
|
||||
feature5 |= 0x00008000; // xdrv_30_exs_dimmer.ino
|
||||
#endif
|
||||
#ifdef USE_TASMOTA_SLAVE
|
||||
feature5 |= 0x00010000; // xdrv_31_arduino_slave.ino
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
feature5 |= 0x00010000; // xdrv_31_tasmota_client.ino
|
||||
#endif
|
||||
#ifdef USE_HIH6
|
||||
feature5 |= 0x00020000; // xsns_55_hih_series.ino
|
||||
|
@ -575,14 +575,21 @@ void GetFeatures(void)
|
|||
#ifdef USE_BL0940
|
||||
feature6 |= 0x00004000; // xnrg_14_bl0940.ino
|
||||
#endif
|
||||
#ifdef USE_TELEINFO
|
||||
feature6 |= 0x00008000; // xnrg_15_teleinfo.ino
|
||||
#ifdef USE_TELEGRAM
|
||||
feature6 |= 0x00008000; // xdrv_40_telegram.ino
|
||||
#endif
|
||||
#ifdef USE_HP303B
|
||||
feature6 |= 0x00010000; // xsns_73_hp303b.ino
|
||||
#endif
|
||||
#ifdef USE_TCP_BRIDGE
|
||||
feature6 |= 0x00020000; // xdrv_41_tcp_bridge.ino
|
||||
#endif
|
||||
#ifdef USE_TELEINFO
|
||||
feature6 |= 0x00040000; // xnrg_15_teleinfo.ino
|
||||
#endif
|
||||
#ifdef USE_LMT01
|
||||
feature6 |= 0x00080000; // xsns_74_lmt01.ino
|
||||
#endif
|
||||
|
||||
// feature6 |= 0x00010000;
|
||||
// feature6 |= 0x00020000;
|
||||
// feature6 |= 0x00040000;
|
||||
// feature6 |= 0x00080000;
|
||||
|
||||
// feature6 |= 0x00100000;
|
||||
// feature6 |= 0x00200000;
|
||||
|
@ -596,8 +603,10 @@ void GetFeatures(void)
|
|||
|
||||
// feature6 |= 0x10000000;
|
||||
// feature6 |= 0x20000000;
|
||||
// feature6 |= 0x40000000;
|
||||
#ifdef USE_ETHERNET
|
||||
feature6 |= 0x40000000; // xdrv_82_ethernet.ino
|
||||
#endif
|
||||
#ifdef USE_WEBCAM
|
||||
feature6 |= 0x80000000;
|
||||
feature6 |= 0x80000000; // xdrv_81_webcam.ino
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
support_network.ino - Network support for Tasmota
|
||||
|
||||
Copyright (C) 2020 Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*********************************************************************************************\
|
||||
* MDNS
|
||||
\*********************************************************************************************/
|
||||
|
||||
struct {
|
||||
uint8_t begun = 0; // mDNS active
|
||||
} Mdns;
|
||||
|
||||
#ifdef USE_DISCOVERY
|
||||
void StartMdns(void) {
|
||||
if (Settings.flag3.mdns_enabled) { // SetOption55 - Control mDNS service
|
||||
if (!Mdns.begun) {
|
||||
// if (mdns_delayed_start) {
|
||||
// AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION));
|
||||
// mdns_delayed_start--;
|
||||
// } else {
|
||||
// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START];
|
||||
Mdns.begun = (uint8_t)MDNS.begin(my_hostname);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Mdns.begun) ? D_INITIALIZED : D_FAILED);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MQTT_HOST_DISCOVERY
|
||||
void MqttDiscoverServer(void)
|
||||
{
|
||||
if (!Mdns.begun) { return; }
|
||||
|
||||
int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service
|
||||
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n);
|
||||
|
||||
if (n > 0) {
|
||||
uint32_t i = 0; // If the hostname isn't set, use the first record found.
|
||||
#ifdef MDNS_HOSTNAME
|
||||
for (i = n; i > 0; i--) { // Search from last to first and use first if not found
|
||||
if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) {
|
||||
break; // Stop at matching record
|
||||
}
|
||||
}
|
||||
#endif // MDNS_HOSTNAME
|
||||
SettingsUpdateText(SET_MQTT_HOST, MDNS.IP(i).toString().c_str());
|
||||
Settings.mqtt_port = MDNS.port(i);
|
||||
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(i).c_str(), SettingsText(SET_MQTT_HOST), Settings.mqtt_port);
|
||||
}
|
||||
}
|
||||
#endif // MQTT_HOST_DISCOVERY
|
||||
|
||||
#ifdef WEBSERVER_ADVERTISE
|
||||
void MdnsAddServiceHttp(void) {
|
||||
if (1 == Mdns.begun) {
|
||||
Mdns.begun = 2;
|
||||
MDNS.addService("http", "tcp", WEB_PORT);
|
||||
}
|
||||
}
|
||||
|
||||
void MdnsUpdate(void) {
|
||||
if (2 == Mdns.begun) {
|
||||
MDNS.update();
|
||||
AddLog_P(LOG_LEVEL_DEBUG_MORE, D_LOG_MDNS, "MDNS.update");
|
||||
}
|
||||
}
|
||||
#endif // WEBSERVER_ADVERTISE
|
||||
#endif // USE_DISCOVERY
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Global network parameters
|
||||
\*********************************************************************************************/
|
||||
|
||||
char* NetworkHostname(void) {
|
||||
if (global_state.eth_down) {
|
||||
return my_hostname;
|
||||
}
|
||||
#ifdef ESP32
|
||||
#ifdef USE_ETHERNET
|
||||
else {
|
||||
return EthernetHostname();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
IPAddress NetworkAddress(void) {
|
||||
if (global_state.eth_down) {
|
||||
return WiFi.localIP();
|
||||
}
|
||||
#ifdef ESP32
|
||||
#ifdef USE_ETHERNET
|
||||
else {
|
||||
return EthernetLocalIP();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
String NetworkMacAddress(void) {
|
||||
if (global_state.eth_down) {
|
||||
return WiFi.macAddress();
|
||||
}
|
||||
#ifdef ESP32
|
||||
#ifdef USE_ETHERNET
|
||||
else {
|
||||
return EthernetMacAddress();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
|
@ -206,6 +206,14 @@ String GetDateAndTime(uint8_t time_type)
|
|||
break;
|
||||
}
|
||||
String dt = GetDT(time); // 2017-03-07T11:08:02
|
||||
|
||||
if (DT_LOCAL_MILLIS == time_type) {
|
||||
char ms[10];
|
||||
snprintf_P(ms, sizeof(ms), PSTR(".%03d"), RtcMillis());
|
||||
dt += ms;
|
||||
time_type = DT_LOCAL;
|
||||
}
|
||||
|
||||
if (Settings.flag3.time_append_timezone && (DT_LOCAL == time_type)) { // SetOption52 - Append timezone to JSON time
|
||||
dt += GetTimeZone(); // 2017-03-07T11:08:02-07:00
|
||||
}
|
||||
|
@ -371,7 +379,7 @@ void RtcSecond(void)
|
|||
Rtc.millis = millis();
|
||||
|
||||
if (!Rtc.user_time_entry) {
|
||||
if (!global_state.wifi_down) {
|
||||
if (!global_state.network_down) {
|
||||
uint8_t uptime_minute = (uptime / 60) % 60; // 0 .. 59
|
||||
if ((Rtc.ntp_sync_minute > 59) && (uptime_minute > 2)) {
|
||||
Rtc.ntp_sync_minute = 1; // If sync prepare for a new cycle
|
||||
|
|
|
@ -684,10 +684,14 @@ void MqttShowState(void)
|
|||
MqttShowPWMState();
|
||||
}
|
||||
|
||||
int32_t rssi = WiFi.RSSI();
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_RSSI "\":%d,\"" D_JSON_SIGNAL "\":%d,\"" D_JSON_LINK_COUNT "\":%d,\"" D_JSON_DOWNTIME "\":\"%s\"}}"),
|
||||
Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WiFi.BSSIDstr().c_str(), WiFi.channel(),
|
||||
WifiGetRssiAsQuality(rssi), rssi, WifiLinkCount(), WifiDowntime().c_str());
|
||||
if (!global_state.wifi_down) {
|
||||
int32_t rssi = WiFi.RSSI();
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_RSSI "\":%d,\"" D_JSON_SIGNAL "\":%d,\"" D_JSON_LINK_COUNT "\":%d,\"" D_JSON_DOWNTIME "\":\"%s\"}"),
|
||||
Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WiFi.BSSIDstr().c_str(), WiFi.channel(),
|
||||
WifiGetRssiAsQuality(rssi), rssi, WifiLinkCount(), WifiDowntime().c_str());
|
||||
}
|
||||
|
||||
ResponseJsonEnd();
|
||||
}
|
||||
|
||||
void MqttPublishTeleState(void)
|
||||
|
@ -824,7 +828,7 @@ void PerformEverySecond(void)
|
|||
|
||||
if (Settings.tele_period) {
|
||||
if (tele_period >= 9999) {
|
||||
if (!global_state.wifi_down) {
|
||||
if (!global_state.network_down) {
|
||||
tele_period = 0; // Allow teleperiod once wifi is connected
|
||||
}
|
||||
} else {
|
||||
|
@ -916,10 +920,12 @@ void Every250mSeconds(void)
|
|||
state_250mS++;
|
||||
state_250mS &= 0x3;
|
||||
|
||||
if (!Settings.flag.global_state) { // Problem blinkyblinky enabled - SetOption31 - Control link led blinking
|
||||
if (global_state.data) { // Any problem
|
||||
global_state.network_down = (global_state.wifi_down && global_state.eth_down);
|
||||
|
||||
if (!Settings.flag.global_state && !global_state.network_down) { // SetOption31 - Control link led blinking
|
||||
if (global_state.data &0x03) { // Any problem
|
||||
if (global_state.mqtt_down) { blinkinterval = 7; } // MQTT problem so blink every 2 seconds (slowest)
|
||||
if (global_state.wifi_down) { blinkinterval = 3; } // Wifi problem so blink every second (slow)
|
||||
if (global_state.network_down) { blinkinterval = 3; } // Network problem so blink every second (slow)
|
||||
blinks = 201; // Allow only a single blink in case the problem is solved
|
||||
}
|
||||
}
|
||||
|
@ -1151,11 +1157,75 @@ void Every250mSeconds(void)
|
|||
}
|
||||
break;
|
||||
case 2: // Every x.5 second
|
||||
WifiCheck(wifi_state_flag);
|
||||
wifi_state_flag = WIFI_RESTART;
|
||||
if (Settings.flag4.network_wifi) {
|
||||
WifiCheck(wifi_state_flag);
|
||||
wifi_state_flag = WIFI_RESTART;
|
||||
}
|
||||
break;
|
||||
case 3: // Every x.75 second
|
||||
if (!global_state.wifi_down) { MqttCheck(); }
|
||||
if (!global_state.network_down) {
|
||||
#ifdef FIRMWARE_MINIMAL
|
||||
if (1 == RtcSettings.ota_loader) {
|
||||
RtcSettings.ota_loader = 0;
|
||||
ota_state_flag = 3;
|
||||
}
|
||||
#endif // FIRMWARE_MINIMAL
|
||||
|
||||
#ifdef USE_DISCOVERY
|
||||
StartMdns();
|
||||
#endif // USE_DISCOVERY
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
if (Settings.webserver) {
|
||||
|
||||
#ifdef ESP8266
|
||||
StartWebserver(Settings.webserver, WiFi.localIP());
|
||||
#else // ESP32
|
||||
#ifdef USE_ETHERNET
|
||||
StartWebserver(Settings.webserver, (EthernetLocalIP()) ? EthernetLocalIP() : WiFi.localIP());
|
||||
#else
|
||||
StartWebserver(Settings.webserver, WiFi.localIP());
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_DISCOVERY
|
||||
#ifdef WEBSERVER_ADVERTISE
|
||||
MdnsAddServiceHttp();
|
||||
#endif // WEBSERVER_ADVERTISE
|
||||
#endif // USE_DISCOVERY
|
||||
} else {
|
||||
StopWebserver();
|
||||
}
|
||||
#ifdef USE_EMULATION
|
||||
if (Settings.flag2.emulation) { UdpConnect(); }
|
||||
#endif // USE_EMULATION
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
DeviceGroupsStart();
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
|
||||
#ifdef USE_KNX
|
||||
if (!knx_started && Settings.flag.knx_enabled) { // CMND_KNX_ENABLED
|
||||
KNXStart();
|
||||
knx_started = true;
|
||||
}
|
||||
#endif // USE_KNX
|
||||
|
||||
MqttCheck();
|
||||
} else {
|
||||
#ifdef USE_EMULATION
|
||||
UdpDisconnect();
|
||||
#endif // USE_EMULATION
|
||||
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
DeviceGroupsStop();
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
|
||||
#ifdef USE_KNX
|
||||
knx_started = false;
|
||||
#endif // USE_KNX
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1174,7 +1244,7 @@ uint16_t arduino_ota_progress_dot_count = 0;
|
|||
void ArduinoOTAInit(void)
|
||||
{
|
||||
ArduinoOTA.setPort(8266);
|
||||
ArduinoOTA.setHostname(my_hostname);
|
||||
ArduinoOTA.setHostname(NetworkHostname());
|
||||
if (strlen(SettingsText(SET_WEBPWD))) {
|
||||
ArduinoOTA.setPassword(SettingsText(SET_WEBPWD));
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@ struct WIFI {
|
|||
uint8_t status;
|
||||
uint8_t config_type = 0;
|
||||
uint8_t config_counter = 0;
|
||||
uint8_t mdns_begun = 0; // mDNS active
|
||||
uint8_t scan_state;
|
||||
uint8_t bssid[6];
|
||||
int8_t best_network_db;
|
||||
|
@ -352,6 +351,9 @@ void WifiSetState(uint8_t state)
|
|||
}
|
||||
}
|
||||
global_state.wifi_down = state ^1;
|
||||
if (!global_state.wifi_down) {
|
||||
global_state.network_down = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if LWIP_IPV6
|
||||
|
@ -410,10 +412,7 @@ void WifiCheckIp(void)
|
|||
Wifi.status = WL_CONNECTED;
|
||||
#ifdef USE_DISCOVERY
|
||||
#ifdef WEBSERVER_ADVERTISE
|
||||
if (2 == Wifi.mdns_begun) {
|
||||
MDNS.update();
|
||||
AddLog_P(LOG_LEVEL_DEBUG_MORE, D_LOG_MDNS, "MDNS.update");
|
||||
}
|
||||
MdnsUpdate();
|
||||
#endif // USE_DISCOVERY
|
||||
#endif // WEBSERVER_ADVERTISE
|
||||
} else {
|
||||
|
@ -529,75 +528,14 @@ void WifiCheck(uint8_t param)
|
|||
if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0) && !Wifi.config_type) {
|
||||
#endif // LWIP_IPV6=1
|
||||
WifiSetState(1);
|
||||
|
||||
if (Settings.flag3.use_wifi_rescan) { // SetOption57 - Scan wifi network every 44 minutes for configured AP's
|
||||
if (!(uptime % (60 * WIFI_RESCAN_MINUTES))) {
|
||||
Wifi.scan_state = 2;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FIRMWARE_MINIMAL
|
||||
if (1 == RtcSettings.ota_loader) {
|
||||
RtcSettings.ota_loader = 0;
|
||||
ota_state_flag = 3;
|
||||
}
|
||||
#endif // FIRMWARE_MINIMAL
|
||||
|
||||
#ifdef USE_DISCOVERY
|
||||
if (Settings.flag3.mdns_enabled) { // SetOption55 - Control mDNS service
|
||||
if (!Wifi.mdns_begun) {
|
||||
// if (mdns_delayed_start) {
|
||||
// AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION));
|
||||
// mdns_delayed_start--;
|
||||
// } else {
|
||||
// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START];
|
||||
Wifi.mdns_begun = (uint8_t)MDNS.begin(my_hostname);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Wifi.mdns_begun) ? D_INITIALIZED : D_FAILED);
|
||||
// }
|
||||
}
|
||||
}
|
||||
#endif // USE_DISCOVERY
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
if (Settings.webserver) {
|
||||
StartWebserver(Settings.webserver, WiFi.localIP());
|
||||
#ifdef USE_DISCOVERY
|
||||
#ifdef WEBSERVER_ADVERTISE
|
||||
if (1 == Wifi.mdns_begun) {
|
||||
Wifi.mdns_begun = 2;
|
||||
MDNS.addService("http", "tcp", WEB_PORT);
|
||||
}
|
||||
#endif // WEBSERVER_ADVERTISE
|
||||
#endif // USE_DISCOVERY
|
||||
} else {
|
||||
StopWebserver();
|
||||
}
|
||||
#ifdef USE_EMULATION
|
||||
if (Settings.flag2.emulation) { UdpConnect(); }
|
||||
#endif // USE_EMULATION
|
||||
#endif // USE_WEBSERVER
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
DeviceGroupsStart();
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
#ifdef USE_KNX
|
||||
if (!knx_started && Settings.flag.knx_enabled) { // CMND_KNX_ENABLED
|
||||
KNXStart();
|
||||
knx_started = true;
|
||||
}
|
||||
#endif // USE_KNX
|
||||
|
||||
} else {
|
||||
WifiSetState(0);
|
||||
#ifdef USE_EMULATION
|
||||
UdpDisconnect();
|
||||
#endif // USE_EMULATION
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
DeviceGroupsStop();
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
Wifi.mdns_begun = 0;
|
||||
#ifdef USE_KNX
|
||||
knx_started = false;
|
||||
#endif // USE_KNX
|
||||
Mdns.begun = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -652,6 +590,8 @@ RF_PRE_INIT()
|
|||
|
||||
void WifiConnect(void)
|
||||
{
|
||||
if (!Settings.flag4.network_wifi) { return; }
|
||||
|
||||
WifiSetState(0);
|
||||
WifiSetOutputPower();
|
||||
WiFi.persistent(false); // Solve possible wifi init errors
|
||||
|
@ -760,4 +700,4 @@ void wifiKeepAlive(void) {
|
|||
SetNextTimeInterval(wifiTimer, wifiTimerSec * 1000);
|
||||
}
|
||||
}
|
||||
#endif // ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
#endif // ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
|
|
|
@ -203,7 +203,8 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to
|
|||
#define KNX_SLOT3 28
|
||||
#define KNX_SLOT4 29
|
||||
#define KNX_SLOT5 30
|
||||
#define KNX_MAX_device_param 30
|
||||
#define KNX_SCENE 31
|
||||
#define KNX_MAX_device_param 31
|
||||
#define MAX_KNXTX_CMNDS 5
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -214,7 +215,7 @@ enum WeekInMonthOptions {Last, First, Second, Third, Fourth};
|
|||
enum DayOfTheWeekOptions {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat};
|
||||
enum MonthNamesOptions {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
|
||||
enum HemisphereOptions {North, South};
|
||||
enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_LOCALNOTZ, DT_DST, DT_STD, DT_RESTART, DT_ENERGY, DT_BOOTCOUNT };
|
||||
enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_LOCALNOTZ, DT_DST, DT_STD, DT_RESTART, DT_ENERGY, DT_BOOTCOUNT, DT_LOCAL_MILLIS };
|
||||
|
||||
enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE};
|
||||
|
||||
|
@ -293,7 +294,7 @@ enum SettingsTextIndex { SET_OTAURL,
|
|||
SET_TEMPLATE_NAME,
|
||||
SET_DEV_GROUP_NAME1, SET_DEV_GROUP_NAME2, SET_DEV_GROUP_NAME3, SET_DEV_GROUP_NAME4,
|
||||
SET_DEVICENAME,
|
||||
SET_TELEGRAMTOKEN,
|
||||
SET_TELEGRAM_TOKEN, SET_TELEGRAM_CHATID,
|
||||
SET_MAX };
|
||||
|
||||
enum DevGroupMessageType { DGR_MSGTYP_FULL_STATUS, DGR_MSGTYP_PARTIAL_UPDATE, DGR_MSGTYP_UPDATE, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_MSGTYP_UPDATE_DIRECT, DGR_MSGTYPE_UPDATE_COMMAND };
|
||||
|
@ -321,9 +322,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE
|
|||
|
||||
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
||||
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
|
||||
SRC_THERMOSTAT, SRC_MAX };
|
||||
SRC_THERMOSTAT, SRC_CHAT, SRC_MAX };
|
||||
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
|
||||
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|Thermostat";
|
||||
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
|
||||
"Thermostat|Chat";
|
||||
|
||||
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
||||
|
||||
|
@ -344,10 +346,10 @@ const SerConfu8 kTasmotaSerialConfig[] PROGMEM = {
|
|||
SERIAL_5O2, SERIAL_6O2, SERIAL_7O2, SERIAL_8O2
|
||||
};
|
||||
|
||||
enum TuyaSupportedFunctions { TUYA_MCU_FUNC_NONE, TUYA_MCU_FUNC_SWT1 = 1, TUYA_MCU_FUNC_SWT2, TUYA_MCU_FUNC_SWT3, TUYA_MCU_FUNC_SWT4,
|
||||
TUYA_MCU_FUNC_REL1 = 11, TUYA_MCU_FUNC_REL2, TUYA_MCU_FUNC_REL3, TUYA_MCU_FUNC_REL4, TUYA_MCU_FUNC_REL5,
|
||||
enum TuyaSupportedFunctions { TUYA_MCU_FUNC_NONE, TUYA_MCU_FUNC_SWT1 = 1, TUYA_MCU_FUNC_SWT2, TUYA_MCU_FUNC_SWT3, TUYA_MCU_FUNC_SWT4,
|
||||
TUYA_MCU_FUNC_REL1 = 11, TUYA_MCU_FUNC_REL2, TUYA_MCU_FUNC_REL3, TUYA_MCU_FUNC_REL4, TUYA_MCU_FUNC_REL5,
|
||||
TUYA_MCU_FUNC_REL6, TUYA_MCU_FUNC_REL7, TUYA_MCU_FUNC_REL8, TUYA_MCU_FUNC_DIMMER = 21, TUYA_MCU_FUNC_POWER = 31,
|
||||
TUYA_MCU_FUNC_CURRENT, TUYA_MCU_FUNC_VOLTAGE, TUYA_MCU_FUNC_BATTERY_STATE, TUYA_MCU_FUNC_BATTERY_PERCENTAGE,
|
||||
TUYA_MCU_FUNC_CURRENT, TUYA_MCU_FUNC_VOLTAGE, TUYA_MCU_FUNC_BATTERY_STATE, TUYA_MCU_FUNC_BATTERY_PERCENTAGE,
|
||||
TUYA_MCU_FUNC_REL1_INV = 41, TUYA_MCU_FUNC_REL2_INV, TUYA_MCU_FUNC_REL3_INV, TUYA_MCU_FUNC_REL4_INV, TUYA_MCU_FUNC_REL5_INV,
|
||||
TUYA_MCU_FUNC_REL6_INV, TUYA_MCU_FUNC_REL7_INV, TUYA_MCU_FUNC_REL8_INV, TUYA_MCU_FUNC_LOWPOWER_MODE = 51, TUYA_MCU_FUNC_LAST = 255
|
||||
};
|
||||
|
|
|
@ -36,9 +36,9 @@
|
|||
#include "tasmota_version.h" // Tasmota version information
|
||||
#include "tasmota.h" // Enumeration used in my_user_config.h
|
||||
#include "my_user_config.h" // Fixed user configurable options
|
||||
#ifdef USE_MQTT_TLS
|
||||
#ifdef USE_TLS
|
||||
#include <t_bearssl.h> // We need to include before "tasmota_globals.h" to take precedence over the BearSSL version in Arduino
|
||||
#endif // USE_MQTT_TLS
|
||||
#endif // USE_TLS
|
||||
#include "tasmota_globals.h" // Function prototypes and global configuration
|
||||
#include "i18n.h" // Language support configured by my_user_config.h
|
||||
#include "tasmota_template.h" // Hardware configuration
|
||||
|
@ -111,9 +111,9 @@ uint32_t uptime = 0; // Counting every second until 42949
|
|||
uint32_t loop_load_avg = 0; // Indicative loop load average
|
||||
uint32_t global_update = 0; // Timestamp of last global temperature and humidity update
|
||||
uint32_t web_log_index = 1; // Index in Web log buffer (should never be 0)
|
||||
float global_temperature = 9999; // Provide a global temperature to be used by some sensors
|
||||
float global_humidity = 0; // Provide a global humidity to be used by some sensors
|
||||
float global_pressure = 0; // Provide a global pressure to be used by some sensors
|
||||
float global_temperature = NAN; // Provide a global temperature to be used by some sensors
|
||||
float global_humidity = 0.0f; // Provide a global humidity to be used by some sensors
|
||||
float global_pressure = 0.0f; // Provide a global pressure to be used by some sensors
|
||||
uint16_t tele_period = 9999; // Tele period timer
|
||||
uint16_t blink_counter = 0; // Number of blink cycles
|
||||
uint16_t seriallog_timer = 0; // Timer to disable Seriallog
|
||||
|
@ -205,7 +205,7 @@ void setup(void) {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
global_state.data = 3; // Init global state (wifi_down, mqtt_down) to solve possible network issues
|
||||
global_state.data = 0xF; // Init global state (wifi_down, mqtt_down) to solve possible network issues
|
||||
|
||||
RtcRebootLoad();
|
||||
if (!RtcRebootValid()) {
|
||||
|
@ -278,12 +278,8 @@ void setup(void) {
|
|||
#endif
|
||||
}
|
||||
if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +4) { // Restarted 6 times
|
||||
#ifdef ESP8266
|
||||
Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic
|
||||
// Settings.last_module = SONOFF_BASIC;
|
||||
#else // ESP32
|
||||
Settings.module = WEMOS; // Reset module to Wemos
|
||||
#endif // ESP8266 - ESP32
|
||||
Settings.module = Settings.fallback_module; // Reset module to fallback module
|
||||
// Settings.last_module = Settings.fallback_module;
|
||||
}
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count);
|
||||
}
|
||||
|
@ -322,6 +318,11 @@ void setup(void) {
|
|||
|
||||
XdrvCall(FUNC_INIT);
|
||||
XsnsCall(FUNC_INIT);
|
||||
#ifdef USE_SCRIPT
|
||||
Run_Scripter(">BS",3,0);
|
||||
#endif
|
||||
|
||||
rules_flag.system_init = 1;
|
||||
}
|
||||
|
||||
void BacklogLoop(void) {
|
||||
|
@ -411,7 +412,7 @@ void loop(void) {
|
|||
if (my_activity < (uint32_t)ssleep) {
|
||||
SleepDelay((uint32_t)ssleep - my_activity); // Provide time for background tasks like wifi
|
||||
} else {
|
||||
if (global_state.wifi_down) {
|
||||
if (global_state.network_down) {
|
||||
SleepDelay(my_activity /2); // If wifi down and my_activity > setoption36 then force loop delay to 1/3 of my_activity period
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,8 @@
|
|||
// Please use fingerprint validation instead
|
||||
// However, the CA are available below for future use if it appears to be useful
|
||||
|
||||
#ifdef USE_MQTT_TLS_CA_CERT
|
||||
#if defined(USE_TLS) && defined(USE_MQTT_TLS_CA_CERT)
|
||||
|
||||
#ifndef USE_MQTT_AWS_IOT
|
||||
/*********************************************************************************************\
|
||||
* LetsEncrypt IdenTrust DST Root CA X3 certificate, RSA 2048 bits SHA 256, valid until 20210417
|
||||
*
|
||||
|
@ -35,7 +34,7 @@
|
|||
* remove "static" and add "PROGMEM"
|
||||
\*********************************************************************************************/
|
||||
|
||||
static const unsigned char PROGMEM TA0_DN[] = {
|
||||
static const unsigned char PROGMEM LetsEncrypt_DN[] = {
|
||||
0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A,
|
||||
0x13, 0x0D, 0x4C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6E, 0x63, 0x72,
|
||||
|
@ -45,7 +44,7 @@ static const unsigned char PROGMEM TA0_DN[] = {
|
|||
0x79, 0x20, 0x58, 0x33
|
||||
};
|
||||
|
||||
static const unsigned char PROGMEM TA0_RSA_N[] = {
|
||||
static const unsigned char PROGMEM LetsEncrypt_RSA_N[] = {
|
||||
0x9C, 0xD3, 0x0C, 0xF0, 0x5A, 0xE5, 0x2E, 0x47, 0xB7, 0x72, 0x5D, 0x37,
|
||||
0x83, 0xB3, 0x68, 0x63, 0x30, 0xEA, 0xD7, 0x35, 0x26, 0x19, 0x25, 0xE1,
|
||||
0xBD, 0xBE, 0x35, 0xF1, 0x70, 0x92, 0x2F, 0xB7, 0xB8, 0x4B, 0x41, 0x05,
|
||||
|
@ -70,27 +69,22 @@ static const unsigned char PROGMEM TA0_RSA_N[] = {
|
|||
0xD8, 0x7D, 0xC3, 0x93
|
||||
};
|
||||
|
||||
static const unsigned char TA0_RSA_E[] = {
|
||||
static const unsigned char LetsEncrypt_RSA_E[] = {
|
||||
0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
static const br_x509_trust_anchor PROGMEM LetsEncryptX3CrossSigned_TA = {
|
||||
{ (unsigned char *)TA0_DN, sizeof TA0_DN },
|
||||
{ (unsigned char *)LetsEncrypt_DN, sizeof LetsEncrypt_DN },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
BR_KEYTYPE_RSA,
|
||||
{ .rsa = {
|
||||
(unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N,
|
||||
(unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E,
|
||||
(unsigned char *)LetsEncrypt_RSA_N, sizeof LetsEncrypt_RSA_N,
|
||||
(unsigned char *)LetsEncrypt_RSA_E, sizeof LetsEncrypt_RSA_E,
|
||||
} }
|
||||
}
|
||||
};
|
||||
|
||||
#define TAs_NUM 1
|
||||
|
||||
#endif // not USE_MQTT_AWS_IOT
|
||||
|
||||
#ifdef USE_MQTT_AWS_IOT
|
||||
/*********************************************************************************************\
|
||||
* Amazon Root CA, RSA 2048 bits SHA 256, valid until 20380117
|
||||
*
|
||||
|
@ -103,7 +97,7 @@ static const br_x509_trust_anchor PROGMEM LetsEncryptX3CrossSigned_TA = {
|
|||
\*********************************************************************************************/
|
||||
|
||||
|
||||
const unsigned char PROGMEM TA0_DN[] = {
|
||||
const unsigned char PROGMEM AmazonRootCA1_DN[] = {
|
||||
0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A,
|
||||
0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17,
|
||||
|
@ -111,7 +105,7 @@ const unsigned char PROGMEM TA0_DN[] = {
|
|||
0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31
|
||||
};
|
||||
|
||||
const unsigned char PROGMEM TA0_RSA_N[] = {
|
||||
const unsigned char PROGMEM AmazonRootCA1_RSA_N[] = {
|
||||
0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80,
|
||||
0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7,
|
||||
0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86,
|
||||
|
@ -136,24 +130,79 @@ const unsigned char PROGMEM TA0_RSA_N[] = {
|
|||
0x9A, 0xC8, 0xAA, 0x0D
|
||||
};
|
||||
|
||||
static const unsigned char PROGMEM TA0_RSA_E[] = {
|
||||
static const unsigned char PROGMEM AmazonRootCA1_RSA_E[] = {
|
||||
0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
const br_x509_trust_anchor PROGMEM AmazonRootCA1_TA = {
|
||||
{ (unsigned char *)TA0_DN, sizeof TA0_DN },
|
||||
{ (unsigned char *)AmazonRootCA1_DN, sizeof AmazonRootCA1_DN },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
BR_KEYTYPE_RSA,
|
||||
{ .rsa = {
|
||||
(unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N,
|
||||
(unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E,
|
||||
(unsigned char *)AmazonRootCA1_RSA_N, sizeof AmazonRootCA1_RSA_N,
|
||||
(unsigned char *)AmazonRootCA1_RSA_E, sizeof AmazonRootCA1_RSA_E,
|
||||
} }
|
||||
}
|
||||
};
|
||||
|
||||
#define TAs_NUM 1
|
||||
// we add a separate CA for telegram
|
||||
/*********************************************************************************************\
|
||||
* GoDaddy Daddy Secure Certificate Authority - G2, RSA 2048 bits SHA 256, valid until 20220523
|
||||
*
|
||||
* to convert do: "brssl ta GoDaddyCA.pem"
|
||||
* then copy and paste below, chain the generic names to the same as below
|
||||
* remove "static" and add "PROGMEM"
|
||||
\*********************************************************************************************/
|
||||
|
||||
#endif // USE_MQTT_AWS_IOT
|
||||
const unsigned char GoDaddyCAG2_DN[] PROGMEM = {
|
||||
0x30, 0x3E, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13,
|
||||
0x18, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, 0x43, 0x6F, 0x6E, 0x74,
|
||||
0x72, 0x6F, 0x6C, 0x20, 0x56, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x65,
|
||||
0x64, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10,
|
||||
0x61, 0x70, 0x69, 0x2E, 0x74, 0x65, 0x6C, 0x65, 0x67, 0x72, 0x61, 0x6D,
|
||||
0x2E, 0x6F, 0x72, 0x67
|
||||
};
|
||||
|
||||
#endif // USE_MQTT_TLS_CA_CERT
|
||||
const unsigned char GoDaddyCAG2_RSA_N[] PROGMEM = {
|
||||
0xB4, 0xA3, 0x16, 0x9E, 0x5C, 0x57, 0xC9, 0x89, 0x65, 0xED, 0xEA, 0x78,
|
||||
0x0B, 0xAE, 0x8A, 0x58, 0x2F, 0xAE, 0x5A, 0xC8, 0x6E, 0x49, 0x8D, 0xFC,
|
||||
0x57, 0xA5, 0x98, 0x88, 0x78, 0x2E, 0x0B, 0x3C, 0x40, 0x3C, 0x21, 0x2E,
|
||||
0x9A, 0x94, 0x98, 0x33, 0xA7, 0xE3, 0x42, 0xA7, 0x85, 0xFA, 0xD0, 0x73,
|
||||
0x84, 0x01, 0x1C, 0x72, 0x39, 0x37, 0x23, 0xB5, 0x56, 0x1D, 0x43, 0xA5,
|
||||
0x71, 0x14, 0x08, 0x24, 0xA5, 0x39, 0xCC, 0xDE, 0x58, 0x53, 0x94, 0x8E,
|
||||
0x2A, 0x42, 0xA7, 0x4E, 0x2D, 0x07, 0x32, 0x9E, 0xBA, 0x8B, 0xD3, 0x2A,
|
||||
0xA9, 0x9E, 0xC0, 0xE3, 0xCE, 0x9A, 0x10, 0x96, 0x45, 0x58, 0x7A, 0xC7,
|
||||
0x1E, 0x45, 0x14, 0x23, 0x92, 0xBB, 0x54, 0x82, 0x88, 0x94, 0x49, 0xB6,
|
||||
0xBE, 0x81, 0x21, 0x00, 0x29, 0x6D, 0xC9, 0xCE, 0x8B, 0x39, 0x3A, 0xDC,
|
||||
0x35, 0x15, 0xD9, 0xEB, 0x47, 0x9C, 0xEF, 0xBA, 0x09, 0x0E, 0x16, 0xE4,
|
||||
0xD9, 0xEB, 0x72, 0x30, 0xFA, 0x49, 0xAB, 0x98, 0x31, 0x7C, 0xB3, 0xAC,
|
||||
0x2B, 0x29, 0x91, 0x87, 0x08, 0x41, 0x72, 0x5E, 0x35, 0xC7, 0x87, 0x04,
|
||||
0x22, 0xF5, 0x48, 0x76, 0x30, 0x6D, 0x88, 0xDF, 0xF2, 0xA5, 0x29, 0x13,
|
||||
0x70, 0xB3, 0x87, 0x02, 0xD5, 0x6B, 0x58, 0xB1, 0xE8, 0x73, 0xC7, 0xE4,
|
||||
0xEF, 0x79, 0x86, 0xA4, 0x07, 0x5F, 0x67, 0xB4, 0x79, 0x8D, 0xA4, 0x25,
|
||||
0x01, 0x82, 0x8C, 0xE0, 0x30, 0x17, 0xCB, 0x4B, 0x5C, 0xFB, 0xEB, 0x4C,
|
||||
0x12, 0x51, 0xB9, 0xC9, 0x04, 0x1F, 0x7E, 0xD2, 0xF8, 0xBA, 0xF5, 0x35,
|
||||
0x8D, 0x8A, 0x1C, 0x37, 0x82, 0xF0, 0x15, 0x73, 0x00, 0x6E, 0x3D, 0x1C,
|
||||
0x76, 0x8B, 0x01, 0x74, 0x81, 0x3D, 0xE4, 0x2C, 0xA7, 0xCC, 0x2F, 0x66,
|
||||
0xDC, 0x44, 0xA8, 0x27, 0x3F, 0xEA, 0xD0, 0xA7, 0xA8, 0xF1, 0xCB, 0xEA,
|
||||
0xDA, 0x07, 0x38, 0xBD
|
||||
};
|
||||
|
||||
const unsigned char GoDaddyCAG2_RSA_E[] PROGMEM = {
|
||||
0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
const br_x509_trust_anchor GoDaddyCAG2_TA PROGMEM = {
|
||||
{ (unsigned char *)GoDaddyCAG2_DN, sizeof GoDaddyCAG2_DN },
|
||||
0,
|
||||
{
|
||||
BR_KEYTYPE_RSA,
|
||||
{ .rsa = {
|
||||
(unsigned char *)GoDaddyCAG2_RSA_N, sizeof GoDaddyCAG2_RSA_N,
|
||||
(unsigned char *)GoDaddyCAG2_RSA_E, sizeof GoDaddyCAG2_RSA_E,
|
||||
} }
|
||||
}
|
||||
};
|
||||
|
||||
#endif // defined(USE_TLS) && defined(USE_MQTT_TLS_CA_CERT)
|
||||
|
|
|
@ -152,9 +152,10 @@
|
|||
#define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code)
|
||||
//#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
|
||||
#define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
|
||||
//#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
|
||||
//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
|
||||
//#define USE_OPENTHERM // Add support for OpenTherm (+15k code)
|
||||
//#define USE_MCP9808 // Add support for MCP9808 temperature sensor (+0k9 code)
|
||||
//#define USE_HP303B // Add support for HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code)
|
||||
|
||||
#define USE_ENERGY_SENSOR // Add energy sensors (-14k code)
|
||||
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
|
||||
|
@ -167,7 +168,7 @@
|
|||
#define USE_DDSU666 // Add support for Chint DDSU666 Modbus energy monitor (+0k6 code)
|
||||
//#define USE_SOLAX_X1 // Add support for Solax X1 series Modbus log info (+3k1 code)
|
||||
//#define USE_LE01MR // Add support for F&F LE-01MR modbus energy meter (+2k code)
|
||||
//#define USE_TELEINFO // Add support for French Energy Provider metering telemetry
|
||||
//#define USE_TELEINFO // Add support for French Energy Provider metering telemetry (+5k2 code, +168 RAM + SmartMeter LinkedList Values RAM)
|
||||
|
||||
#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor
|
||||
#define USE_MAX31855 // Add support for MAX31855 K-Type thermocouple sensor using softSPI
|
||||
|
@ -175,6 +176,7 @@
|
|||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
|
||||
#define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram)
|
||||
|
||||
#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code)
|
||||
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
|
||||
#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code)
|
||||
#define USE_HX711 // Add support for HX711 load cell (+1k5 code)
|
||||
|
@ -381,7 +383,7 @@
|
|||
#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code)
|
||||
#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
|
||||
#undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
|
||||
#undef USE_TASMOTA_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
|
||||
#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
|
||||
#undef USE_OPENTHERM // Disable support for OpenTherm (+15k code)
|
||||
|
||||
//#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor
|
||||
|
@ -486,7 +488,7 @@
|
|||
#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code)
|
||||
#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
|
||||
#undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
|
||||
#undef USE_TASMOTA_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
|
||||
#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
|
||||
#undef USE_OPENTHERM // Disable support for OpenTherm (+15k code)
|
||||
|
||||
//#undef USE_ENERGY_SENSOR // Disable energy sensors
|
||||
|
@ -613,7 +615,7 @@
|
|||
#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code)
|
||||
#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
|
||||
#undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
|
||||
#undef USE_TASMOTA_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
|
||||
#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
|
||||
#undef USE_OPENTHERM // Disable support for OpenTherm (+15k code)
|
||||
|
||||
#undef USE_ENERGY_SENSOR // Disable energy sensors
|
||||
|
|
|
@ -43,6 +43,16 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
|
|||
extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack, uint32_t stack_end);
|
||||
extern "C" void resetPins();
|
||||
|
||||
#ifdef ESP32
|
||||
|
||||
#ifdef USE_ETHERNET
|
||||
IPAddress EthernetLocalIP(void);
|
||||
char* EthernetHostname(void);
|
||||
String EthernetMacAddress(void);
|
||||
#endif
|
||||
|
||||
#endif // ESP32
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Preconfigured configurations
|
||||
\*********************************************************************************************/
|
||||
|
@ -59,6 +69,18 @@ extern "C" void resetPins();
|
|||
#ifdef USE_EMULATION_WEMO
|
||||
#define USE_EMULATION
|
||||
#endif
|
||||
|
||||
// Convert legacy slave to client
|
||||
#ifdef USE_TASMOTA_SLAVE
|
||||
#define USE_TASMOTA_CLIENT
|
||||
#endif
|
||||
#ifdef USE_TASMOTA_SLAVE_FLASH_SPEED
|
||||
#define USE_TASMOTA_CLIENT_FLASH_SPEED USE_TASMOTA_SLAVE_FLASH_SPEED
|
||||
#endif
|
||||
#ifdef USE_TASMOTA_SLAVE_SERIAL_SPEED
|
||||
#define USE_TASMOTA_CLIENT_SERIAL_SPEED USE_TASMOTA_SLAVE_SERIAL_SPEED
|
||||
#endif
|
||||
|
||||
// See https://github.com/esp8266/Arduino/pull/4889
|
||||
#undef NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions)
|
||||
|
||||
|
@ -88,7 +110,7 @@ extern "C" void resetPins();
|
|||
const uint16_t WEB_LOG_SIZE = 4000; // Max number of characters in weblog
|
||||
#endif
|
||||
|
||||
#if defined(USE_MQTT_TLS) && defined(ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||
#if defined(USE_TLS) && defined(ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||
#error "TLS is no more supported on Core 2.3.0, use 2.4.2 or higher."
|
||||
#endif
|
||||
|
||||
|
@ -277,6 +299,9 @@ const char kWebColors[] PROGMEM =
|
|||
#ifndef MODULE
|
||||
#define MODULE SONOFF_BASIC // [Module] Select default model
|
||||
#endif
|
||||
#ifndef FALLBACK_MODULE
|
||||
#define FALLBACK_MODULE SONOFF_BASIC // [Module2] Select default module on fast reboot where USER_MODULE is user template
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINO_ESP8266_RELEASE
|
||||
#define ARDUINO_CORE_RELEASE "STAGE"
|
||||
|
@ -291,6 +316,9 @@ const char kWebColors[] PROGMEM =
|
|||
#ifndef MODULE
|
||||
#define MODULE WEMOS // [Module] Select default model
|
||||
#endif
|
||||
#ifndef FALLBACK_MODULE
|
||||
#define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINO_ESP32_RELEASE
|
||||
#define ARDUINO_CORE_RELEASE "STAGE"
|
||||
|
|
|
@ -137,8 +137,8 @@ enum UserSelectablePins {
|
|||
GPIO_TUYA_RX, // Tuya Serial interface
|
||||
GPIO_MGC3130_XFER, // MGC3130 Transfer
|
||||
GPIO_MGC3130_RESET, // MGC3130 Reset
|
||||
GPIO_SSPI_MISO, // Software SPI Master Input Slave Output
|
||||
GPIO_SSPI_MOSI, // Software SPI Master Output Slave Input
|
||||
GPIO_SSPI_MISO, // Software SPI Master Input Client Output
|
||||
GPIO_SSPI_MOSI, // Software SPI Master Output Client Input
|
||||
GPIO_SSPI_SCLK, // Software SPI Serial Clock
|
||||
GPIO_SSPI_CS, // Software SPI Chip Select
|
||||
GPIO_SSPI_DC, // Software SPI Data or Command
|
||||
|
@ -210,10 +210,10 @@ enum UserSelectablePins {
|
|||
GPIO_SM2135_DAT, // SM2135 Dat
|
||||
GPIO_DEEPSLEEP, // Kill switch for deepsleep
|
||||
GPIO_EXS_ENABLE, // EXS MCU Enable
|
||||
GPIO_TASMOTASLAVE_TXD, // Slave TX
|
||||
GPIO_TASMOTASLAVE_RXD, // Slave RX
|
||||
GPIO_TASMOTASLAVE_RST, // Slave Reset Pin
|
||||
GPIO_TASMOTASLAVE_RST_INV, // Slave Reset Inverted
|
||||
GPIO_TASMOTACLIENT_TXD, // Client TX
|
||||
GPIO_TASMOTACLIENT_RXD, // Client RX
|
||||
GPIO_TASMOTACLIENT_RST, // Client Reset Pin
|
||||
GPIO_TASMOTACLIENT_RST_INV, // Client Reset Inverted
|
||||
GPIO_HPMA_RX, // Honeywell HPMA115S0 Serial interface
|
||||
GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface
|
||||
GPIO_GPS_RX, // GPS serial interface
|
||||
|
@ -234,8 +234,11 @@ enum UserSelectablePins {
|
|||
GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin
|
||||
GPIO_WINDMETER_SPEED, // WindMeter speed counter pin
|
||||
GPIO_BL0940_RX, // BL0940 serial interface
|
||||
GPIO_TELEINFO_RX, // BL0940 serial interface
|
||||
GPIO_TELEINFO_ENABLE, // BL0940 serial interface
|
||||
GPIO_TCP_TX, // TCP Serial bridge
|
||||
GPIO_TCP_RX, // TCP Serial bridge
|
||||
GPIO_TELEINFO_RX, // TELEINFO serial interface
|
||||
GPIO_TELEINFO_ENABLE,// TELEINFO Enable PIN
|
||||
GPIO_LMT01, // LMT01 input counting pin
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
// Programmer selectable GPIO functionality
|
||||
|
@ -314,7 +317,7 @@ const char kSensorNames[] PROGMEM =
|
|||
D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|"
|
||||
D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|"
|
||||
D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|"
|
||||
D_SENSOR_SLAVE_TX "|" D_SENSOR_SLAVE_RX "|" D_SENSOR_SLAVE_RESET "|" D_SENSOR_SLAVE_RESET "i|"
|
||||
D_SENSOR_CLIENT_TX "|" D_SENSOR_CLIENT_RX "|" D_SENSOR_CLIENT_RESET "|" D_SENSOR_CLIENT_RESET "i|"
|
||||
D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|"
|
||||
D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|"
|
||||
D_SENSOR_DS18X20 "o|" D_SENSOR_DHT11 "o|"
|
||||
|
@ -326,8 +329,10 @@ const char kSensorNames[] PROGMEM =
|
|||
D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX "|"
|
||||
D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|"
|
||||
D_SENSOR_WINDMETER_SPEED "|"
|
||||
D_SENSOR_BL0940_RX "|"
|
||||
D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE
|
||||
D_SENSOR_BL0940_RX "|"
|
||||
D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|"
|
||||
D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|"
|
||||
D_SENSOR_LMT01_PULSE
|
||||
;
|
||||
|
||||
const char kSensorNamesFixed[] PROGMEM =
|
||||
|
@ -427,8 +432,8 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
|||
#ifdef USE_SPI
|
||||
GPIO_SPI_CS, // SPI Chip Select
|
||||
GPIO_SPI_DC, // SPI Data Direction
|
||||
GPIO_SSPI_MISO, // Software SPI Master Input Slave Output
|
||||
GPIO_SSPI_MOSI, // Software SPI Master Output Slave Input
|
||||
GPIO_SSPI_MISO, // Software SPI Master Input Client Output
|
||||
GPIO_SSPI_MOSI, // Software SPI Master Output Client Input
|
||||
GPIO_SSPI_SCLK, // Software SPI Serial Clock
|
||||
GPIO_SSPI_CS, // Software SPI Chip Select
|
||||
GPIO_SSPI_DC, // Software SPI Data or Command
|
||||
|
@ -447,6 +452,9 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
|||
GPIO_DSB, // Single wire DS18B20 or DS18S20
|
||||
GPIO_DSB_OUT, // Pseudo Single wire DS18B20 or DS18S20
|
||||
#endif
|
||||
#ifdef USE_LMT01 // LMT01, count pulses on GPIO
|
||||
GPIO_LMT01,
|
||||
#endif
|
||||
|
||||
// Light
|
||||
#ifdef USE_LIGHT
|
||||
|
@ -577,6 +585,10 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
|||
GPIO_SBR_TX, // Serial Bridge Serial interface
|
||||
GPIO_SBR_RX, // Serial Bridge Serial interface
|
||||
#endif
|
||||
#ifdef USE_TCP_BRIDGE
|
||||
GPIO_TCP_TX, // TCP Serial bridge
|
||||
GPIO_TCP_RX, // TCP Serial bridge
|
||||
#endif
|
||||
#ifdef USE_ZIGBEE
|
||||
GPIO_ZIGBEE_TX, // Zigbee Serial interface
|
||||
GPIO_ZIGBEE_RX, // Zigbee Serial interface
|
||||
|
@ -618,11 +630,11 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
|||
GPIO_PN532_TXD, // PN532 HSU Tx
|
||||
GPIO_PN532_RXD, // PN532 HSU Rx
|
||||
#endif
|
||||
#ifdef USE_TASMOTA_SLAVE
|
||||
GPIO_TASMOTASLAVE_TXD, // Tasmota Slave TX
|
||||
GPIO_TASMOTASLAVE_RXD, // Tasmota Slave RX
|
||||
GPIO_TASMOTASLAVE_RST, // Tasmota Slave Reset
|
||||
GPIO_TASMOTASLAVE_RST_INV, // Tasmota Slave Reset Inverted
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
GPIO_TASMOTACLIENT_TXD, // Tasmota Client TX
|
||||
GPIO_TASMOTACLIENT_RXD, // Tasmota Client RX
|
||||
GPIO_TASMOTACLIENT_RST, // Tasmota Client Reset
|
||||
GPIO_TASMOTACLIENT_RST_INV, // Tasmota Client Reset Inverted
|
||||
#endif
|
||||
#ifdef USE_RDM6300
|
||||
GPIO_RDM6300_RX,
|
||||
|
@ -689,7 +701,6 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
|||
GPIO_TELEINFO_RX,
|
||||
GPIO_TELEINFO_ENABLE,
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/********************************************************************************************/
|
||||
|
@ -777,8 +788,8 @@ enum SupportedModules {
|
|||
SUPLA1, WITTY, YUNSHAN, MAGICHOME, LUANIHVIO, KMC_70011, ARILUX_LC01, ARILUX_LC11, SONOFF_DUAL_R2, ARILUX_LC06,
|
||||
SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH,
|
||||
OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4,
|
||||
OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1,
|
||||
SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, DENKY,
|
||||
OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1,
|
||||
SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1,
|
||||
MAXMODULE};
|
||||
|
||||
#define USER_MODULE 255
|
||||
|
@ -791,7 +802,7 @@ const char kModuleNames[] PROGMEM =
|
|||
"Sonoff S31|Zengge WF017|Sonoff Pow R2|Sonoff iFan02|BlitzWolf SHP|Shelly 1|Shelly 2|Xiaomi Philips|Neo Coolcam|ESP Switch|"
|
||||
"OBI Socket|Teckin|AplicWDP303075|Tuya MCU|Gosund SP1 v23|ARMTR Dimmer|SK03 Outdoor|PS-16-DZ|Teckin US|Manzoku strip|"
|
||||
"OBI Socket 2|YTF IR Bridge|Digoo DG-SP202|KA10|Luminea ZX2820|Mi Desk Lamp|SP10|WAGA CHCZ02MB|SYF05|Sonoff L1|"
|
||||
"Sonoff iFan03|EXS Dimmer|PWM Dimmer|Sonoff D1|Denky (Teleinfo)"
|
||||
"Sonoff iFan03|EXS Dimmer|PWM Dimmer|Sonoff D1"
|
||||
;
|
||||
|
||||
const uint8_t kModuleNiceList[] PROGMEM = {
|
||||
|
@ -2174,26 +2185,6 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
|||
GPIO_LED1_INV, // GPIO13 WiFi Blue Led - Link and Power status
|
||||
0, 0, 0, 0
|
||||
},
|
||||
{ // Denky (Teleinfo) Any ESP8266 device
|
||||
GPIO_WS2812, // GPIO00 WS2812 RGB LED
|
||||
GPIO_USER, // GPIO01 TX Serial RXD
|
||||
GPIO_USER, // GPIO02 D4 Wemos DHT Shield
|
||||
GPIO_TELEINFO_RX, // GPIO03 Smart Meter RX Serial
|
||||
GPIO_I2C_SDA, // GPIO04 D2 Wemos I2C SDA
|
||||
GPIO_I2C_SCL, // GPIO05 D1 Wemos I2C SCL
|
||||
// GPIO06 (SD_CLK Flash)
|
||||
// GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
|
||||
// GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
|
||||
GPIO_USER, // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
|
||||
GPIO_USER, // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
|
||||
// GPIO11 (SD_CMD Flash)
|
||||
GPIO_USER, // GPIO12 D6
|
||||
GPIO_USER, // GPIO13 D7
|
||||
GPIO_USER, // GPIO14 D5
|
||||
GPIO_USER, // GPIO15 D8
|
||||
GPIO_USER, // GPIO16 D0 Wemos Wake
|
||||
ADC0_USER // ADC0 A0 Analog input
|
||||
},
|
||||
{ // SONOFF_IFAN03 - Sonoff iFan03 (ESP8285)
|
||||
GPIO_KEY1, // GPIO00 WIFI_KEY0 Button 1
|
||||
GPIO_TXD, // GPIO01 ESP_TXD Serial RXD connection to P0.5 of RF microcontroller
|
||||
|
@ -2278,10 +2269,8 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
|||
GPIO_LED1_INV, // GPIO13 WiFi Blue Led - Link and Power status
|
||||
0, 0, 0, 0
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // ESP8266
|
||||
|
||||
#ifdef ESP32
|
||||
|
|
|
@ -102,8 +102,8 @@ enum UserSelectablePins {
|
|||
GPIO_SM2135_CLK, GPIO_SM2135_DAT, // SM2135 PWM controller
|
||||
GPIO_DEEPSLEEP, // Kill switch for deepsleep
|
||||
GPIO_EXS_ENABLE, // EXS MCU Enable
|
||||
GPIO_TASMOTASLAVE_TXD, GPIO_TASMOTASLAVE_RXD, // Slave Serial interface
|
||||
GPIO_TASMOTASLAVE_RST, GPIO_TASMOTASLAVE_RST_INV, // Slave Reset
|
||||
GPIO_TASMOTACLIENT_TXD, GPIO_TASMOTACLIENT_RXD, // Client Serial interface
|
||||
GPIO_TASMOTACLIENT_RST, GPIO_TASMOTACLIENT_RST_INV, // Client Reset
|
||||
GPIO_HPMA_RX, GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface
|
||||
GPIO_GPS_RX, GPIO_GPS_TX, // GPS Serial interface
|
||||
GPIO_HM10_RX, GPIO_HM10_TX, // HM10-BLE-Mijia-bridge Serial interface
|
||||
|
@ -133,6 +133,7 @@ enum UserSelectablePins {
|
|||
GPIO_ETH_PHY_POWER, GPIO_ETH_PHY_MDC, GPIO_ETH_PHY_MDIO, // Ethernet
|
||||
GPIO_TELEINFO_RX, // Teleinfo telemetry data receive pin
|
||||
GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin
|
||||
GPIO_LMT01, // LMT01 input counting pin
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
enum ProgramSelectablePins {
|
||||
|
@ -199,7 +200,7 @@ const char kSensorNames[] PROGMEM =
|
|||
D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|"
|
||||
D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|"
|
||||
D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|"
|
||||
D_SENSOR_SLAVE_TX "|" D_SENSOR_SLAVE_RX "|" D_SENSOR_SLAVE_RESET "|" D_SENSOR_SLAVE_RESET "_i|"
|
||||
D_SENSOR_CLIENT_TX "|" D_SENSOR_CLIENT_RX "|" D_SENSOR_CLIENT_RESET "|" D_SENSOR_CLIENT_RESET "_i|"
|
||||
D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|"
|
||||
D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|"
|
||||
D_SENSOR_HM10_RX "|" D_SENSOR_HM10_TX "|"
|
||||
|
@ -225,7 +226,8 @@ const char kSensorNames[] PROGMEM =
|
|||
D_SENSOR_BL0940_RX "|"
|
||||
D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|"
|
||||
D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO "|"
|
||||
D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE
|
||||
D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|"
|
||||
D_SENSOR_LMT01_PULSE
|
||||
;
|
||||
|
||||
const char kSensorNamesFixed[] PROGMEM =
|
||||
|
@ -269,8 +271,8 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
|||
AGPIO(GPIO_SPI_CLK), // SPI Clk
|
||||
AGPIO(GPIO_SPI_CS), // SPI Chip Select
|
||||
AGPIO(GPIO_SPI_DC), // SPI Data Direction
|
||||
AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Slave Output
|
||||
AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Slave Input
|
||||
AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output
|
||||
AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input
|
||||
AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock
|
||||
AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select
|
||||
AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command
|
||||
|
@ -293,6 +295,9 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
|||
AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20
|
||||
AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20
|
||||
#endif
|
||||
#ifdef USE_LMT01
|
||||
AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO
|
||||
#endif
|
||||
|
||||
// Light
|
||||
#ifdef USE_LIGHT
|
||||
|
@ -468,11 +473,11 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
|||
AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx
|
||||
AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx
|
||||
#endif
|
||||
#ifdef USE_TASMOTA_SLAVE
|
||||
AGPIO(GPIO_TASMOTASLAVE_TXD), // Tasmota Slave TX
|
||||
AGPIO(GPIO_TASMOTASLAVE_RXD), // Tasmota Slave RX
|
||||
AGPIO(GPIO_TASMOTASLAVE_RST), // Tasmota Slave Reset
|
||||
AGPIO(GPIO_TASMOTASLAVE_RST_INV), // Tasmota Slave Reset Inverted
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX
|
||||
AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX
|
||||
AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset
|
||||
AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted
|
||||
#endif
|
||||
#ifdef USE_RDM6300
|
||||
AGPIO(GPIO_RDM6300_RX),
|
||||
|
@ -685,12 +690,12 @@ const mytmplt kModules PROGMEM =
|
|||
/*********************************************************************************************\
|
||||
Known templates
|
||||
|
||||
{"NAME":"AITHINKER CAM","GPIO":[4992,65504,65504,65504,65504,5088,65504,65504,65504,65504,65504,65504,65504,65504,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,65504,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1}
|
||||
{"NAME":"Olimex ESP32-PoE","GPIO":[65504,65504,65504,65504,65504,65504,0,0,5536,65504,65504,65504,65504,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1}
|
||||
{"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1}
|
||||
{"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
||||
{"NAME":"wESP32","GPIO":[1,1,1,1,1,1,0,0,0,1,1,1,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
||||
|
||||
\*********************************************************************************************/
|
||||
|
||||
|
||||
#endif // ESP32
|
||||
|
||||
#endif // _TASMOTA_TEMPLATE_ESP32_H_
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef _TASMOTA_VERSION_H_
|
||||
#define _TASMOTA_VERSION_H_
|
||||
|
||||
const uint32_t VERSION = 0x08030102;
|
||||
const uint32_t VERSION = 0x08030106;
|
||||
|
||||
// Lowest compatible version
|
||||
const uint32_t VERSION_COMPATIBLE = 0x07010006;
|
||||
|
|
|
@ -44,7 +44,7 @@ const uint16_t HTTP_OTA_RESTART_RECONNECT_TIME = 28000; // milliseconds - Allow
|
|||
uint8_t *efm8bb1_update = nullptr;
|
||||
#endif // USE_RF_FLASH
|
||||
|
||||
enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTASLAVE };
|
||||
enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTACLIENT };
|
||||
|
||||
static const char * HEADER_KEYS[] = { "User-Agent", };
|
||||
|
||||
|
@ -868,10 +868,16 @@ void StartWebserver(int type, IPAddress ipweb)
|
|||
if (Web.state != type) {
|
||||
#if LWIP_IPV6
|
||||
String ipv6_addr = WifiGetIPv6();
|
||||
if(ipv6_addr!="") AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s and IPv6 global address %s "), my_hostname, (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str(),ipv6_addr.c_str());
|
||||
else AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), my_hostname, (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str());
|
||||
if (ipv6_addr!="") {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s and IPv6 global address %s "),
|
||||
NetworkHostname(), (Mdns.begun) ? ".local" : "", ipweb.toString().c_str(), ipv6_addr.c_str());
|
||||
} else {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"),
|
||||
NetworkHostname(), (Mdns.begun) ? ".local" : "", ipweb.toString().c_str());
|
||||
}
|
||||
#else
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), my_hostname, (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str());
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"),
|
||||
NetworkHostname(), (Mdns.begun) ? ".local" : "", ipweb.toString().c_str());
|
||||
#endif // LWIP_IPV6 = 1
|
||||
rules_flag.http_init = 1;
|
||||
}
|
||||
|
@ -1151,8 +1157,8 @@ void WSContentSendStyle_P(const char* formatP, ...)
|
|||
bool lip = (static_cast<uint32_t>(WiFi.localIP()) != 0);
|
||||
bool sip = (static_cast<uint32_t>(WiFi.softAPIP()) != 0);
|
||||
WSContentSend_P(PSTR("<h4>%s%s (%s%s%s)</h4>"), // tasmota.local (192.168.2.12, 192.168.4.1)
|
||||
my_hostname,
|
||||
(Wifi.mdns_begun) ? ".local" : "",
|
||||
NetworkHostname(),
|
||||
(Mdns.begun) ? ".local" : "",
|
||||
(lip) ? WiFi.localIP().toString().c_str() : "",
|
||||
(lip && sip) ? ", " : "",
|
||||
(sip) ? WiFi.softAPIP().toString().c_str() : "");
|
||||
|
@ -2016,8 +2022,8 @@ void ModuleSaveSettings(void)
|
|||
|
||||
/*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
const char kUnescapeCode[] = "&><\"\'";
|
||||
const char kEscapeCode[] PROGMEM = "&|>|<|"|'";
|
||||
const char kUnescapeCode[] = "&><\"\'\\";
|
||||
const char kEscapeCode[] PROGMEM = "&|>|<|"|'|\";
|
||||
|
||||
String HtmlEscape(const String unescaped) {
|
||||
char escaped[10];
|
||||
|
@ -2321,22 +2327,6 @@ void OtherSaveSettings(void)
|
|||
}
|
||||
AddLog_P(LOG_LEVEL_INFO, message);
|
||||
|
||||
/*
|
||||
// This sometimes provides intermittent watchdog
|
||||
bool template_activate = Webserver->hasArg("t2"); // Try this to tackle intermittent watchdog after execution of Template command
|
||||
WebGetArg("t1", tmp, sizeof(tmp));
|
||||
if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255}
|
||||
char svalue[128];
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_TEMPLATE " %s"), tmp);
|
||||
ExecuteWebCommand(svalue, SRC_WEBGUI);
|
||||
|
||||
if (template_activate) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_MODULE " 0"));
|
||||
ExecuteWebCommand(svalue, SRC_WEBGUI);
|
||||
}
|
||||
}
|
||||
// Try async execution of commands
|
||||
*/
|
||||
WebGetArg("t1", tmp, sizeof(tmp));
|
||||
if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255}
|
||||
snprintf_P(message, sizeof(message), PSTR(D_CMND_BACKLOG " " D_CMND_TEMPLATE " %s%s"), tmp, (Webserver->hasArg("t2")) ? "; " D_CMND_MODULE " 0" : "");
|
||||
|
@ -2471,26 +2461,42 @@ void HandleInformation(void)
|
|||
WSContentSend_P(PSTR("}1" D_FRIENDLY_NAME " %d}2%s"), i +1, SettingsText(SET_FRIENDLYNAME1 +i));
|
||||
}
|
||||
WSContentSend_P(PSTR("}1}2 ")); // Empty line
|
||||
int32_t rssi = WiFi.RSSI();
|
||||
WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WifiGetRssiAsQuality(rssi), rssi);
|
||||
WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), my_hostname, (Wifi.mdns_begun) ? ".local" : "");
|
||||
#ifdef ESP32
|
||||
#ifdef USE_ETHERNET
|
||||
if (static_cast<uint32_t>(EthernetLocalIP()) != 0) {
|
||||
WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? ".local" : "");
|
||||
WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str());
|
||||
WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (eth)}2%s"), EthernetLocalIP().toString().c_str());
|
||||
WSContentSend_P(PSTR("}1<hr/>}2<hr/>"));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (Settings.flag4.network_wifi) {
|
||||
int32_t rssi = WiFi.RSSI();
|
||||
WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, HtmlEscape(SettingsText(SET_STASSID1 + Settings.sta_active)).c_str(), WifiGetRssiAsQuality(rssi), rssi);
|
||||
WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), my_hostname, (Mdns.begun) ? ".local" : "");
|
||||
#if LWIP_IPV6
|
||||
String ipv6_addr = WifiGetIPv6();
|
||||
if(ipv6_addr != ""){
|
||||
if (ipv6_addr != "") {
|
||||
WSContentSend_P(PSTR("}1 IPv6 Address }2%s"), ipv6_addr.c_str());
|
||||
}
|
||||
#endif
|
||||
if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
|
||||
WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), WiFi.localIP().toString().c_str());
|
||||
if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
|
||||
WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str());
|
||||
WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (wifi)}2%s"), WiFi.localIP().toString().c_str());
|
||||
WSContentSend_P(PSTR("}1<hr/>}2<hr/>"));
|
||||
}
|
||||
}
|
||||
if (!global_state.network_down) {
|
||||
WSContentSend_P(PSTR("}1" D_GATEWAY "}2%s"), IPAddress(Settings.ip_address[1]).toString().c_str());
|
||||
WSContentSend_P(PSTR("}1" D_SUBNET_MASK "}2%s"), IPAddress(Settings.ip_address[2]).toString().c_str());
|
||||
WSContentSend_P(PSTR("}1" D_DNS_SERVER "}2%s"), IPAddress(Settings.ip_address[3]).toString().c_str());
|
||||
WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str());
|
||||
}
|
||||
if (static_cast<uint32_t>(WiFi.softAPIP()) != 0) {
|
||||
WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), WiFi.softAPIP().toString().c_str());
|
||||
WSContentSend_P(PSTR("}1" D_GATEWAY "}2%s"), WiFi.softAPIP().toString().c_str());
|
||||
if ((WiFi.getMode() >= WIFI_AP) && (static_cast<uint32_t>(WiFi.softAPIP()) != 0)) {
|
||||
WSContentSend_P(PSTR("}1<hr/>}2<hr/>"));
|
||||
WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.softAPmacAddress().c_str());
|
||||
WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (AP)}2%s"), WiFi.softAPIP().toString().c_str());
|
||||
WSContentSend_P(PSTR("}1" D_GATEWAY "}2%s"), WiFi.softAPIP().toString().c_str());
|
||||
}
|
||||
WSContentSend_P(PSTR("}1}2 ")); // Empty line
|
||||
if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT
|
||||
|
@ -2645,8 +2651,8 @@ void HandleUploadDone(void)
|
|||
WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "</font></b><br>"), WebColor(COL_TEXT_SUCCESS));
|
||||
WSContentSend_P(HTTP_MSG_RSTRT);
|
||||
ShowWebSource(SRC_WEBGUI);
|
||||
#ifdef USE_TASMOTA_SLAVE
|
||||
if (TasmotaSlave_GetFlagFlashing()) {
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
if (TasmotaClient_GetFlagFlashing()) {
|
||||
restart_flag = 0;
|
||||
} else { // It was a normal firmware file, or we are ready to restart device
|
||||
restart_flag = 2;
|
||||
|
@ -2659,9 +2665,9 @@ void HandleUploadDone(void)
|
|||
WSContentSend_P(PSTR("</div><br>"));
|
||||
WSContentSpaceButton(BUTTON_MAIN);
|
||||
WSContentStop();
|
||||
#ifdef USE_TASMOTA_SLAVE
|
||||
if (TasmotaSlave_GetFlagFlashing()) {
|
||||
TasmotaSlave_Flash();
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
if (TasmotaClient_GetFlagFlashing()) {
|
||||
TasmotaClient_Flash();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -2731,11 +2737,11 @@ void HandleUploadLoop(void)
|
|||
if (Web.upload_error != 0) { return; }
|
||||
} else
|
||||
#endif // USE_RF_FLASH
|
||||
#ifdef USE_TASMOTA_SLAVE
|
||||
if ((WEMOS == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a ARDUINO SLAVE hex file
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
if ((WEMOS == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a ARDUINO CLIENT hex file
|
||||
Update.end(); // End esp8266 update session
|
||||
Web.upload_file_type = UPL_TASMOTASLAVE;
|
||||
Web.upload_error = TasmotaSlave_UpdateInit(); // 0
|
||||
Web.upload_file_type = UPL_TASMOTACLIENT;
|
||||
Web.upload_error = TasmotaClient_UpdateInit(); // 0
|
||||
if (Web.upload_error != 0) { return; }
|
||||
} else
|
||||
#endif
|
||||
|
@ -2799,9 +2805,9 @@ void HandleUploadLoop(void)
|
|||
}
|
||||
}
|
||||
#endif // USE_RF_FLASH
|
||||
#ifdef USE_TASMOTA_SLAVE
|
||||
else if (UPL_TASMOTASLAVE == Web.upload_file_type) {
|
||||
TasmotaSlave_WriteBuffer(upload.buf, upload.currentSize);
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
else if (UPL_TASMOTACLIENT == Web.upload_file_type) {
|
||||
TasmotaClient_WriteBuffer(upload.buf, upload.currentSize);
|
||||
}
|
||||
#endif
|
||||
else { // firmware
|
||||
|
@ -2865,10 +2871,10 @@ void HandleUploadLoop(void)
|
|||
Web.upload_file_type = UPL_TASMOTA;
|
||||
}
|
||||
#endif // USE_RF_FLASH
|
||||
#ifdef USE_TASMOTA_SLAVE
|
||||
else if (UPL_TASMOTASLAVE == Web.upload_file_type) {
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
else if (UPL_TASMOTACLIENT == Web.upload_file_type) {
|
||||
// Done writing the hex to SPI flash
|
||||
TasmotaSlave_SetFlagFlashing(true); // So we know on upload success page if it needs to flash hex or do a normal restart
|
||||
TasmotaClient_SetFlagFlashing(true); // So we know on upload success page if it needs to flash hex or do a normal restart
|
||||
Web.upload_file_type = UPL_TASMOTA;
|
||||
}
|
||||
#endif
|
||||
|
@ -3288,7 +3294,7 @@ void CmndWebServer(void)
|
|||
}
|
||||
if (Settings.webserver) {
|
||||
Response_P(PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_JSON_ACTIVE_FOR " %s " D_JSON_ON_DEVICE " %s " D_JSON_WITH_IP_ADDRESS " %s\"}"),
|
||||
(2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str());
|
||||
(2 == Settings.webserver) ? D_ADMIN : D_USER, NetworkHostname(), NetworkAddress().toString().c_str());
|
||||
} else {
|
||||
ResponseCmndStateText(0);
|
||||
}
|
||||
|
|
|
@ -123,34 +123,6 @@ void MakeValidMqtt(uint32_t option, char* str)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_DISCOVERY
|
||||
#ifdef MQTT_HOST_DISCOVERY
|
||||
void MqttDiscoverServer(void)
|
||||
{
|
||||
if (!Wifi.mdns_begun) { return; }
|
||||
|
||||
int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service
|
||||
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n);
|
||||
|
||||
if (n > 0) {
|
||||
uint32_t i = 0; // If the hostname isn't set, use the first record found.
|
||||
#ifdef MDNS_HOSTNAME
|
||||
for (i = n; i > 0; i--) { // Search from last to first and use first if not found
|
||||
if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) {
|
||||
break; // Stop at matching record
|
||||
}
|
||||
}
|
||||
#endif // MDNS_HOSTNAME
|
||||
SettingsUpdateText(SET_MQTT_HOST, MDNS.IP(i).toString().c_str());
|
||||
Settings.mqtt_port = MDNS.port(i);
|
||||
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(i).c_str(), SettingsText(SET_MQTT_HOST), Settings.mqtt_port);
|
||||
}
|
||||
}
|
||||
#endif // MQTT_HOST_DISCOVERY
|
||||
#endif // USE_DISCOVERY
|
||||
|
||||
/*********************************************************************************************\
|
||||
* MQTT driver specific code need to provide the following functions:
|
||||
*
|
||||
|
@ -539,10 +511,10 @@ void MqttConnected(void)
|
|||
if (Settings.webserver) {
|
||||
#if LWIP_IPV6
|
||||
Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"IPv6Address\":\"%s\"}"),
|
||||
(2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str(),WifiGetIPv6().c_str());
|
||||
(2 == Settings.webserver) ? D_ADMIN : D_USER, NetworkHostname(), NetworkAddress().toString().c_str(), WifiGetIPv6().c_str());
|
||||
#else
|
||||
Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}"),
|
||||
(2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str());
|
||||
(2 == Settings.webserver) ? D_ADMIN : D_USER, NetworkHostname(), NetworkAddress().toString().c_str());
|
||||
#endif // LWIP_IPV6 = 1
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2"));
|
||||
}
|
||||
|
|
|
@ -459,7 +459,12 @@ void EnergyEverySecond(void)
|
|||
{
|
||||
// Overtemp check
|
||||
if (global_update) {
|
||||
if (power && (global_temperature != 9999) && (global_temperature > Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays
|
||||
if (power && !isnan(global_temperature) && (global_temperature > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays
|
||||
|
||||
char temperature[33];
|
||||
dtostrfd(global_temperature, 1, temperature);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %s"), temperature);
|
||||
|
||||
SetAllPower(POWER_ALL_OFF, SRC_OVERTEMP);
|
||||
}
|
||||
}
|
||||
|
@ -1137,6 +1142,9 @@ bool Xdrv03(uint8_t function)
|
|||
case FUNC_EVERY_250_MSECOND:
|
||||
XnrgCall(FUNC_EVERY_250_MSECOND);
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
XnrgCall(FUNC_EVERY_SECOND);
|
||||
break;
|
||||
case FUNC_SERIAL:
|
||||
result = XnrgCall(FUNC_SERIAL);
|
||||
break;
|
||||
|
|
|
@ -1555,10 +1555,10 @@ void LightState(uint8_t append)
|
|||
if (!Light.pwm_multi_channels) {
|
||||
if (unlinked) {
|
||||
// RGB and W are unlinked, we display the second Power/Dimmer
|
||||
ResponseAppend_P(PSTR("\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "%d\":%d"
|
||||
",\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "%d\":%d"),
|
||||
Light.device, GetStateText(Light.power & 1), Light.device, light_state.getDimmer(1),
|
||||
Light.device + 1, GetStateText(Light.power & 2 ? 1 : 0), Light.device + 1, light_state.getDimmer(2));
|
||||
ResponseAppend_P(PSTR("\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "1\":%d"
|
||||
",\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "2\":%d"),
|
||||
Light.device, GetStateText(Light.power & 1), light_state.getDimmer(1),
|
||||
Light.device + 1, GetStateText(Light.power & 2 ? 1 : 0), light_state.getDimmer(2));
|
||||
} else {
|
||||
GetPowerDevice(scommand, Light.device, sizeof(scommand), Settings.flag.device_index_enable); // SetOption26 - Switch between POWER or POWER1
|
||||
ResponseAppend_P(PSTR("\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d"), scommand, GetStateText(Light.power & 1),
|
||||
|
|
|
@ -887,17 +887,18 @@ void RulesEvery50ms(void)
|
|||
rules_flag.data ^= mask;
|
||||
json_event[0] = '\0';
|
||||
switch (i) {
|
||||
case 0: strncpy_P(json_event, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(json_event)); break;
|
||||
case 1: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Initialized\":%d}}"), MinutesPastMidnight()); break;
|
||||
case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), MinutesPastMidnight()); break;
|
||||
case 3: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
||||
case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
||||
case 5: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
||||
case 6: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
||||
case 7: strncpy_P(json_event, PSTR("{\"HTTP\":{\"Initialized\":1}}"), sizeof(json_event)); break;
|
||||
case 0: strncpy_P(json_event, PSTR("{\"System\":{\"Init\":1}}"), sizeof(json_event)); break;
|
||||
case 1: strncpy_P(json_event, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(json_event)); break;
|
||||
case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Initialized\":%d}}"), MinutesPastMidnight()); break;
|
||||
case 3: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), MinutesPastMidnight()); break;
|
||||
case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
||||
case 5: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
||||
case 6: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
||||
case 7: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
||||
case 8: strncpy_P(json_event, PSTR("{\"HTTP\":{\"Initialized\":1}}"), sizeof(json_event)); break;
|
||||
#ifdef USE_SHUTTER
|
||||
case 8: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moved\":1}}"), sizeof(json_event)); break;
|
||||
case 9: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moving\":1}}"), sizeof(json_event)); break;
|
||||
case 9: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moved\":1}}"), sizeof(json_event)); break;
|
||||
case 10: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moving\":1}}"), sizeof(json_event)); break;
|
||||
#endif // USE_SHUTTER
|
||||
}
|
||||
if (json_event[0]) {
|
||||
|
|
|
@ -26,7 +26,6 @@ uses about 17 k of flash
|
|||
|
||||
to do
|
||||
optimize code for space
|
||||
g:var gloabal vars (via udp broadcast)
|
||||
|
||||
remarks
|
||||
|
||||
|
@ -68,6 +67,8 @@ keywords if then else endif, or, and are better readable for beginners (others m
|
|||
uint32_t EncodeLightId(uint8_t relay_id);
|
||||
uint32_t DecodeLightId(uint32_t hue_id);
|
||||
|
||||
|
||||
|
||||
// solve conficting defines
|
||||
// highest priority
|
||||
#ifdef USE_SCRIPT_FATFS
|
||||
|
@ -119,6 +120,31 @@ uint32_t DecodeLightId(uint32_t hue_id);
|
|||
#endif
|
||||
#endif // USE_UNISHOX_COMPRESSION
|
||||
|
||||
#ifdef USE_SCRIPT_TIMER
|
||||
#include <Ticker.h>
|
||||
Ticker Script_ticker1;
|
||||
Ticker Script_ticker2;
|
||||
Ticker Script_ticker3;
|
||||
Ticker Script_ticker4;
|
||||
|
||||
void Script_ticker1_end(void) {
|
||||
Script_ticker1.detach();
|
||||
Run_Scripter(">ti1", 4,0);
|
||||
}
|
||||
void Script_ticker2_end(void) {
|
||||
Script_ticker2.detach();
|
||||
Run_Scripter(">ti2", 4,0);
|
||||
}
|
||||
void Script_ticker3_end(void) {
|
||||
Script_ticker3.detach();
|
||||
Run_Scripter(">ti3", 4,0);
|
||||
}
|
||||
void Script_ticker4_end(void) {
|
||||
Script_ticker4.detach();
|
||||
Run_Scripter(">ti4", 4,0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(LITTLEFS_SCRIPT_SIZE) || (USE_SCRIPT_FATFS==-1)
|
||||
#ifdef ESP32
|
||||
|
@ -237,7 +263,11 @@ extern VButton *buttons[MAXBUTTONS];
|
|||
#endif
|
||||
|
||||
typedef union {
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
uint16_t data;
|
||||
#else
|
||||
uint8_t data;
|
||||
#endif
|
||||
struct {
|
||||
uint8_t is_string : 1; // string or number
|
||||
uint8_t is_permanent : 1;
|
||||
|
@ -247,6 +277,9 @@ typedef union {
|
|||
uint8_t settable : 1;
|
||||
uint8_t is_filter : 1;
|
||||
uint8_t constant : 1;
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
uint8_t global : 1;
|
||||
#endif
|
||||
};
|
||||
} SCRIPT_TYPE;
|
||||
|
||||
|
@ -276,6 +309,32 @@ typedef union {
|
|||
};
|
||||
} FILE_FLAGS;
|
||||
|
||||
typedef union {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t nutu8 : 1;
|
||||
uint8_t nutu7 : 1;
|
||||
uint8_t nutu6 : 1;
|
||||
uint8_t nutu5 : 1;
|
||||
uint8_t nutu4 : 1;
|
||||
uint8_t nutu3 : 1;
|
||||
uint8_t udp_connected : 1;
|
||||
uint8_t udp_used : 1;
|
||||
};
|
||||
} UDP_FLAGS;
|
||||
|
||||
|
||||
#define NUM_RES 0xfe
|
||||
#define STR_RES 0xfd
|
||||
#define VAR_NV 0xff
|
||||
|
||||
#define NTYPE 0
|
||||
#define STYPE 0x80
|
||||
|
||||
#ifndef FLT_MAX
|
||||
#define FLT_MAX 99999999
|
||||
#endif
|
||||
|
||||
#define SFS_MAX 4
|
||||
// global memory
|
||||
struct SCRIPT_MEM {
|
||||
|
@ -308,12 +367,19 @@ struct SCRIPT_MEM {
|
|||
uint8_t script_sd_found;
|
||||
char flink[2][14];
|
||||
#endif
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
UDP_FLAGS udp_flags;
|
||||
#endif
|
||||
} glob_script_mem;
|
||||
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
IPAddress last_udp_ip;
|
||||
#endif
|
||||
|
||||
int16_t last_findex;
|
||||
uint8_t tasm_cmd_activ=0;
|
||||
uint8_t fast_script=0;
|
||||
uint8_t glob_script=0;
|
||||
uint32_t script_lastmillis;
|
||||
|
||||
|
||||
|
@ -331,7 +397,7 @@ void ScriptEverySecond(void) {
|
|||
|
||||
if (bitRead(Settings.rule_enabled, 0)) {
|
||||
struct T_INDEX *vtp=glob_script_mem.type;
|
||||
float delta=(millis()-script_lastmillis)/1000;
|
||||
float delta=(millis()-script_lastmillis)/1000.0;
|
||||
script_lastmillis=millis();
|
||||
for (uint8_t count=0; count<glob_script_mem.numvars; count++) {
|
||||
if (vtp[count].bits.is_timer) {
|
||||
|
@ -436,6 +502,16 @@ char *script;
|
|||
} else {
|
||||
vtypes[vars].bits.is_autoinc=0;
|
||||
}
|
||||
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
if (*lp=='g' && *(lp+1)==':') {
|
||||
lp+=2;
|
||||
vtypes[vars].bits.global=1;
|
||||
glob_script_mem.udp_flags.udp_used = 1;
|
||||
} else {
|
||||
vtypes[vars].bits.global=0;
|
||||
}
|
||||
#endif
|
||||
if ((*lp=='m' || *lp=='M') && *(lp+1)==':') {
|
||||
uint8_t flg=*lp;
|
||||
lp+=2;
|
||||
|
@ -703,10 +779,112 @@ char *script;
|
|||
// store start of actual program here
|
||||
glob_script_mem.scriptptr=lp-1;
|
||||
glob_script_mem.scriptptr_bu=glob_script_mem.scriptptr;
|
||||
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
if (glob_script_mem.udp_flags.udp_used) {
|
||||
Script_Init_UDP();
|
||||
glob_script=Run_Scripter(">G",-2,0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
#define SCRIPT_UDP_BUFFER_SIZE 128
|
||||
#define SCRIPT_UDP_PORT 1999
|
||||
IPAddress script_udp_remote_ip;
|
||||
|
||||
void Script_Init_UDP() {
|
||||
if (global_state.network_down) return;
|
||||
if (glob_script_mem.udp_flags.udp_connected) return;
|
||||
|
||||
if (PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), SCRIPT_UDP_PORT)) {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP started"));
|
||||
glob_script_mem.udp_flags.udp_connected = 1;
|
||||
} else {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP failed"));
|
||||
glob_script_mem.udp_flags.udp_connected = 0;
|
||||
}
|
||||
}
|
||||
void Script_PollUdp(void) {
|
||||
if (!glob_script_mem.udp_flags.udp_used) return;
|
||||
if (glob_script_mem.udp_flags.udp_connected ) {
|
||||
while (PortUdp.parsePacket()) {
|
||||
char packet_buffer[SCRIPT_UDP_BUFFER_SIZE];
|
||||
int32_t len = PortUdp.read(packet_buffer, SCRIPT_UDP_BUFFER_SIZE -1);
|
||||
packet_buffer[len] = 0;
|
||||
script_udp_remote_ip = PortUdp.remoteIP();
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("UDP: Packet %s - %d - %s"), packet_buffer, len, script_udp_remote_ip.toString().c_str());
|
||||
char *lp=packet_buffer;
|
||||
if (!strncmp(lp,"=>",2)) {
|
||||
lp+=2;
|
||||
char *cp=strchr(lp,'=');
|
||||
if (cp) {
|
||||
char vnam[32];
|
||||
for (uint32_t count=0; count<len; count++) {
|
||||
if (lp[count]=='=') {
|
||||
vnam[count]=0;
|
||||
break;
|
||||
}
|
||||
vnam[count]=lp[count];
|
||||
}
|
||||
float *fp;
|
||||
char *sp;
|
||||
uint32_t index;
|
||||
uint32_t res=match_vars(vnam, &fp, &sp, &index);
|
||||
if (res==NUM_RES) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("num var found - %s - %d"),vnam,res);
|
||||
*fp=CharToFloat(cp+1);
|
||||
} else if (res==STR_RES) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("string var found - %s - %d"),vnam,res);
|
||||
strlcpy(sp,cp+1,SCRIPT_MAXSSIZE);
|
||||
} else {
|
||||
// error var not found
|
||||
}
|
||||
if (res) {
|
||||
// mark changed
|
||||
last_udp_ip=PortUdp.remoteIP();
|
||||
glob_script_mem.type[index].bits.changed=1;
|
||||
if (glob_script==99) {
|
||||
Run_Scripter(">G",2,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
optimistic_yield(100);
|
||||
}
|
||||
} else {
|
||||
Script_Init_UDP();
|
||||
}
|
||||
}
|
||||
|
||||
void script_udp_sendvar(char *vname,float *fp,char *sp) {
|
||||
if (!glob_script_mem.udp_flags.udp_used) return;
|
||||
if (!glob_script_mem.udp_flags.udp_connected) return;
|
||||
|
||||
char sbuf[SCRIPT_MAXSSIZE+4];
|
||||
strcpy(sbuf,"=>");
|
||||
strcat(sbuf,vname);
|
||||
strcat(sbuf,"=");
|
||||
if (fp) {
|
||||
char flstr[16];
|
||||
dtostrfd(*fp,8,flstr);
|
||||
strcat(sbuf,flstr);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("num var updated - %s"),sbuf);
|
||||
} else {
|
||||
strcat(sbuf,sp);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("string var updated - %s"),sbuf);
|
||||
}
|
||||
PortUdp.beginPacket(IPAddress(239,255,255,250), SCRIPT_UDP_PORT);
|
||||
// Udp.print(String("RET UC: ") + String(recv_Packet));
|
||||
PortUdp.write((const uint8_t*)sbuf,strlen(sbuf));
|
||||
PortUdp.endPacket();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHT
|
||||
#ifdef USE_WS2812
|
||||
void ws2812_set_array(float *array ,uint32_t len, uint32_t offset) {
|
||||
|
@ -723,16 +901,7 @@ void ws2812_set_array(float *array ,uint32_t len, uint32_t offset) {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#define NUM_RES 0xfe
|
||||
#define STR_RES 0xfd
|
||||
#define VAR_NV 0xff
|
||||
|
||||
#define NTYPE 0
|
||||
#define STYPE 0x80
|
||||
|
||||
#ifndef FLT_MAX
|
||||
#define FLT_MAX 99999999
|
||||
#endif
|
||||
|
||||
float median_array(float *array,uint8_t len) {
|
||||
uint8_t ind[len];
|
||||
|
@ -1011,6 +1180,37 @@ uint32_t MeasurePulseTime(int32_t in) {
|
|||
}
|
||||
#endif // USE_ANGLE_FUNC
|
||||
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
uint32_t match_vars(char *dvnam, float **fp, char **sp, uint32_t *ind) {
|
||||
uint16_t olen=strlen(dvnam);
|
||||
struct T_INDEX *vtp=glob_script_mem.type;
|
||||
for (uint32_t count=0; count<glob_script_mem.numvars; count++) {
|
||||
char *cp=glob_script_mem.glob_vnp+glob_script_mem.vnp_offset[count];
|
||||
uint8_t slen=strlen(cp);
|
||||
if (slen==olen && *cp==dvnam[0]) {
|
||||
if (!strncmp(cp,dvnam,olen)) {
|
||||
uint8_t index=vtp[count].index;
|
||||
if (vtp[count].bits.is_string==0) {
|
||||
if (vtp[count].bits.is_filter) {
|
||||
// error
|
||||
return 0;
|
||||
} else {
|
||||
*fp=&glob_script_mem.fvars[index];
|
||||
*ind=index;
|
||||
return NUM_RES;
|
||||
}
|
||||
} else {
|
||||
*sp=glob_script_mem.glob_snp+(index*glob_script_mem.max_ssize);
|
||||
*ind=index;
|
||||
return STR_RES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// vtype => ff=nothing found, fe=constant number,fd = constant string else bit 7 => 80 = string, 0 = number
|
||||
// no flash strings here for performance reasons!!!
|
||||
char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,JsonObject *jo) {
|
||||
|
@ -1703,6 +1903,20 @@ chknext:
|
|||
if (sp) strlcpy(sp,SettingsText(SET_MQTT_GRP_TOPIC),glob_script_mem.max_ssize);
|
||||
goto strexit;
|
||||
}
|
||||
|
||||
#ifdef SCRIPT_GET_HTTPS_JP
|
||||
if (!strncmp(vname,"gjp(",4)) {
|
||||
char host[SCRIPT_MAXSSIZE];
|
||||
lp=GetStringResult(lp+4,OPER_EQU,host,0);
|
||||
SCRIPT_SKIP_SPACES
|
||||
char path[SCRIPT_MAXSSIZE];
|
||||
lp=GetStringResult(lp,OPER_EQU,path,0);
|
||||
fvar=call2https(host,path);
|
||||
lp++;
|
||||
len=0;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 'h':
|
||||
if (!strncmp(vname,"hours",5)) {
|
||||
|
@ -1765,12 +1979,40 @@ chknext:
|
|||
len=0;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname,"is(",3)) {
|
||||
lp=GetNumericResult(lp+3,OPER_EQU,&fvar,0);
|
||||
SCRIPT_SKIP_SPACES
|
||||
if (*lp!='"') {
|
||||
break;
|
||||
}
|
||||
lp++;
|
||||
char *sstr=lp;
|
||||
for (uint32_t cnt=0; cnt<256; cnt++) {
|
||||
if (lp[cnt]='\n' || lp[cnt]=='"') {
|
||||
lp+=cnt+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
char str[SCRIPT_MAXSSIZE];
|
||||
GetTextIndexed(str, sizeof(str), fvar, sstr);
|
||||
lp++;
|
||||
if (sp) strlcpy(sp,str,glob_script_mem.max_ssize);
|
||||
fvar=0;
|
||||
len=0;
|
||||
goto exit;
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
if (!strncmp(vname,"lip",3)) {
|
||||
if (sp) strlcpy(sp,(const char*)WiFi.localIP().toString().c_str(),glob_script_mem.max_ssize);
|
||||
goto strexit;
|
||||
}
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
if (!strncmp(vname,"luip",4)) {
|
||||
if (sp) strlcpy(sp,IPAddressToString(last_udp_ip),glob_script_mem.max_ssize);
|
||||
goto strexit;
|
||||
}
|
||||
#endif
|
||||
if (!strncmp(vname,"loglvl",6)) {
|
||||
fvar=glob_script_mem.script_loglevel;
|
||||
tind->index=SCRIPT_LOGLEVEL;
|
||||
|
@ -2209,6 +2451,41 @@ chknext:
|
|||
if (sp) strlcpy(sp,SettingsText(SET_MQTT_TOPIC),glob_script_mem.max_ssize);
|
||||
goto strexit;
|
||||
}
|
||||
#ifdef USE_SCRIPT_TIMER
|
||||
if (!strncmp(vname,"ts1(",4)) {
|
||||
lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
|
||||
if (fvar<10) fvar=10;
|
||||
Script_ticker1.attach_ms(fvar, Script_ticker1_end);
|
||||
lp++;
|
||||
len=0;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname,"ts2(",4)) {
|
||||
lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
|
||||
if (fvar<10) fvar=10;
|
||||
Script_ticker2.attach_ms(fvar, Script_ticker2_end);
|
||||
lp++;
|
||||
len=0;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname,"ts3(",4)) {
|
||||
lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
|
||||
if (fvar<10) fvar=10;
|
||||
Script_ticker3.attach_ms(fvar, Script_ticker3_end);
|
||||
lp++;
|
||||
len=0;
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname,"ts4(",4)) {
|
||||
lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
|
||||
if (fvar<10) fvar=10;
|
||||
Script_ticker4.attach_ms(fvar, Script_ticker4_end);
|
||||
lp++;
|
||||
len=0;
|
||||
goto exit;
|
||||
}
|
||||
#endif // USE_SCRIPT_TIMER
|
||||
|
||||
#ifdef USE_DISPLAY
|
||||
#ifdef USE_TOUCH_BUTTONS
|
||||
if (!strncmp(vname,"tbut[",5)) {
|
||||
|
@ -3167,7 +3444,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||
if (!if_exe[ifstck] && if_state[ifstck]!=1) goto next_line;
|
||||
|
||||
#ifdef IFTHEN_DEBUG
|
||||
sprintf(tbuff,"stack=%d,exe=%d,state=%d,cmpres=%d execute line: ",ifstck,if_exe[ifstck],if_state[ifstck],if_result[ifstck]);
|
||||
sdtoff(tbuff,"stack=%d,exe=%d,state=%d,cmpres=%d execute line: ",ifstck,if_exe[ifstck],if_state[ifstck],if_result[ifstck]);
|
||||
toLogEOL(tbuff,lp);
|
||||
#endif
|
||||
|
||||
|
@ -3382,8 +3659,16 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||
}
|
||||
goto next_line;
|
||||
} else {
|
||||
char *vnp=lp;
|
||||
lp=isvar(lp,&vtype,&ind,&sysvar,0,0);
|
||||
if (vtype!=VAR_NV) {
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
char varname[16];
|
||||
uint32_t vnl=(uint32_t)lp-(uint32)vnp;
|
||||
strncpy(varname,vnp,vnl);
|
||||
varname[vnl]=0;
|
||||
#endif
|
||||
|
||||
// found variable as result
|
||||
globvindex=ind.index; // save destination var index here
|
||||
globaindex=last_findex;
|
||||
|
@ -3451,6 +3736,11 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||
}
|
||||
// var was changed
|
||||
glob_script_mem.type[globvindex].bits.changed=1;
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
if (glob_script_mem.type[globvindex].bits.global) {
|
||||
script_udp_sendvar(varname,dfvar,0);
|
||||
}
|
||||
#endif
|
||||
if (glob_script_mem.type[globvindex].bits.is_filter) {
|
||||
if (globaindex>=0) {
|
||||
Set_MFVal(glob_script_mem.type[globvindex].index,globaindex,*dfvar);
|
||||
|
@ -3492,6 +3782,11 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||
if (!glob_script_mem.var_not_found) {
|
||||
// var was changed
|
||||
glob_script_mem.type[globvindex].bits.changed=1;
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
if (glob_script_mem.type[globvindex].bits.global) {
|
||||
script_udp_sendvar(varname,0,str);
|
||||
}
|
||||
#endif
|
||||
if (lastop==OPER_EQU) {
|
||||
strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
|
||||
} else if (lastop==OPER_PLSEQU) {
|
||||
|
@ -3979,8 +4274,7 @@ void ListDir(char *path, uint8_t depth) {
|
|||
|
||||
char path[48];
|
||||
|
||||
void Script_FileUploadConfiguration(void)
|
||||
{
|
||||
void Script_FileUploadConfiguration(void) {
|
||||
uint8_t depth=0;
|
||||
strcpy(path,"/");
|
||||
|
||||
|
@ -3995,17 +4289,6 @@ void Script_FileUploadConfiguration(void)
|
|||
}
|
||||
}
|
||||
|
||||
void ScriptFileUploadSuccess(void) {
|
||||
WSContentStart_P(S_INFORMATION);
|
||||
WSContentSendStyle();
|
||||
WSContentSend_P(PSTR("<div style='text-align:center;'><b>" D_UPLOAD " <font color='#"));
|
||||
WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "</font></b><br/>"), WebColor(COL_TEXT_SUCCESS));
|
||||
WSContentSend_P(PSTR("</div><br/>"));
|
||||
WSContentSend_P(PSTR("<p><form action='%s' method='get'><button>%s</button></form></p>"),"/upl",D_UPL_DONE);
|
||||
//WSContentSpaceButton(BUTTON_MAIN);
|
||||
WSContentStop();
|
||||
}
|
||||
|
||||
WSContentStart_P(S_SCRIPT_FILE_UPLOAD);
|
||||
WSContentSendStyle();
|
||||
WSContentSend_P(HTTP_FORM_FILE_UPLOAD,D_SDCARD_DIR);
|
||||
|
@ -4023,13 +4306,22 @@ void Script_FileUploadConfiguration(void)
|
|||
Web.upload_error = 0;
|
||||
}
|
||||
|
||||
void ScriptFileUploadSuccess(void) {
|
||||
WSContentStart_P(S_INFORMATION);
|
||||
WSContentSendStyle();
|
||||
WSContentSend_P(PSTR("<div style='text-align:center;'><b>" D_UPLOAD " <font color='#"));
|
||||
WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "</font></b><br/>"), WebColor(COL_TEXT_SUCCESS));
|
||||
WSContentSend_P(PSTR("</div><br/>"));
|
||||
WSContentSend_P(PSTR("<p><form action='%s' method='get'><button>%s</button></form></p>"),"/upl",D_UPL_DONE);
|
||||
//WSContentSpaceButton(BUTTON_MAIN);
|
||||
WSContentStop();
|
||||
}
|
||||
|
||||
|
||||
File upload_file;
|
||||
|
||||
|
||||
void script_upload(void) {
|
||||
|
||||
//AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: file upload"));
|
||||
|
||||
HTTPUpload& upload = Webserver->upload();
|
||||
if (upload.status == UPLOAD_FILE_START) {
|
||||
char npath[48];
|
||||
|
@ -4601,9 +4893,11 @@ void Script_Check_Hue(String *response) {
|
|||
}
|
||||
else {
|
||||
if (hue_devs>0) *response+=",\"";
|
||||
else *response+="\"";
|
||||
}
|
||||
*response+=String(EncodeLightId(hue_devs+devices_present+1))+"\":";
|
||||
Script_HueStatus(response,hue_devs);
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Hue: %s - %d "),response->c_str(), hue_devs);
|
||||
}
|
||||
|
||||
hue_devs++;
|
||||
|
@ -5902,6 +6196,62 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) {
|
|||
|
||||
#endif // USE_SCRIPT_TASK
|
||||
#endif // ESP32
|
||||
|
||||
#ifdef SCRIPT_GET_HTTPS_JP
|
||||
#ifdef ESP8266
|
||||
#include "WiFiClientSecureLightBearSSL.h"
|
||||
#else
|
||||
#include <WiFiClientSecure.h>
|
||||
#endif
|
||||
|
||||
// get tesla powerwall info page json string
|
||||
uint32_t call2https(const char *host, const char *path) {
|
||||
if (global_state.wifi_down) return 1;
|
||||
uint32_t status=0;
|
||||
#ifdef ESP32
|
||||
WiFiClientSecure *httpsClient;
|
||||
httpsClient = new WiFiClientSecure;
|
||||
#else
|
||||
BearSSL::WiFiClientSecure_light *httpsClient;
|
||||
httpsClient = new BearSSL::WiFiClientSecure_light(1024, 1024);
|
||||
#endif
|
||||
|
||||
httpsClient->setTimeout(1500);
|
||||
|
||||
int retry = 0;
|
||||
String result;
|
||||
while ((!httpsClient->connect(host, 443)) && (retry < 5)) {
|
||||
delay(100);
|
||||
retry++;
|
||||
}
|
||||
if (retry == 5) {
|
||||
return 2;
|
||||
}
|
||||
String request = String("GET ") + path +
|
||||
" HTTP/1.1\r\n" +
|
||||
"Host: " + host +
|
||||
"\r\n" + "Connection: close\r\n\r\n";
|
||||
httpsClient->print(request);
|
||||
|
||||
while (httpsClient->connected()) {
|
||||
String line = httpsClient->readStringUntil('\n');
|
||||
if (line == "\r") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (httpsClient->available()) {
|
||||
String line = httpsClient->readStringUntil('\n');
|
||||
if (line!="") {
|
||||
result += line;
|
||||
}
|
||||
}
|
||||
httpsClient->stop();
|
||||
Run_Scripter(">jp",3,(char*)result.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // SCRIPT_GET_HTTPS_JP
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
@ -6139,6 +6489,12 @@ bool Xdrv10(uint8_t function)
|
|||
break;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SCRIPT_GLOBVARS
|
||||
case FUNC_LOOP:
|
||||
Script_PollUdp();
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -114,6 +114,7 @@ device_parameters_t device_param[] = {
|
|||
{ KNX_SLOT3 , false, false, KNX_Empty },
|
||||
{ KNX_SLOT4 , false, false, KNX_Empty },
|
||||
{ KNX_SLOT5 , false, false, KNX_Empty },
|
||||
{ KNX_SCENE , false, false, KNX_Empty },
|
||||
{ KNX_Empty, false, false, KNX_Empty}
|
||||
};
|
||||
|
||||
|
@ -149,6 +150,7 @@ const char * device_param_ga[] = {
|
|||
D_KNX_TX_SLOT " 3",
|
||||
D_KNX_TX_SLOT " 4",
|
||||
D_KNX_TX_SLOT " 5",
|
||||
D_KNX_TX_SCENE ,
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
@ -184,6 +186,7 @@ const char *device_param_cb[] = {
|
|||
D_KNX_RX_SLOT " 3",
|
||||
D_KNX_RX_SLOT " 4",
|
||||
D_KNX_RX_SLOT " 5",
|
||||
D_KNX_RX_SCENE ,
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
@ -196,12 +199,14 @@ const char *device_param_cb[] = {
|
|||
#define D_CMND_KNX_PA "_PA"
|
||||
#define D_CMND_KNX_GA "_GA"
|
||||
#define D_CMND_KNX_CB "_CB"
|
||||
#define D_CMND_KNXTXSCENE "Tx_Scene"
|
||||
|
||||
|
||||
const char kKnxCommands[] PROGMEM = D_PRFX_KNX "|" // Prefix
|
||||
D_CMND_KNXTXCMND "|" D_CMND_KNXTXVAL "|" D_CMND_KNX_ENABLED "|" D_CMND_KNX_ENHANCED "|" D_CMND_KNX_PA "|" D_CMND_KNX_GA "|" D_CMND_KNX_CB ;
|
||||
D_CMND_KNXTXCMND "|" D_CMND_KNXTXVAL "|" D_CMND_KNX_ENABLED "|" D_CMND_KNX_ENHANCED "|" D_CMND_KNX_PA "|" D_CMND_KNX_GA "|" D_CMND_KNX_CB "|" D_CMND_KNXTXSCENE ;
|
||||
|
||||
void (* const KnxCommand[])(void) PROGMEM = {
|
||||
&CmndKnxTxCmnd, &CmndKnxTxVal, &CmndKnxEnabled, &CmndKnxEnhanced, &CmndKnxPa, &CmndKnxGa, &CmndKnxCb };
|
||||
&CmndKnxTxCmnd, &CmndKnxTxVal, &CmndKnxEnabled, &CmndKnxEnhanced, &CmndKnxPa, &CmndKnxGa, &CmndKnxCb, &CmndKnxTxScene };
|
||||
|
||||
uint8_t KNX_GA_Search( uint8_t param, uint8_t start = 0 )
|
||||
{
|
||||
|
@ -518,6 +523,7 @@ void KNX_INIT(void)
|
|||
device_param[KNX_SLOT3-1].show = true;
|
||||
device_param[KNX_SLOT4-1].show = true;
|
||||
device_param[KNX_SLOT5-1].show = true;
|
||||
device_param[KNX_SCENE-1].show = true;
|
||||
#endif
|
||||
|
||||
// Delete from KNX settings all configuration is not anymore related to this device
|
||||
|
@ -557,7 +563,11 @@ void KNX_CB_Action(message_t const &msg, void *arg)
|
|||
if (msg.data_len == 1) {
|
||||
// COMMAND
|
||||
sprintf(tempchar,"%d",msg.data[0]);
|
||||
} else {
|
||||
} else if (chan->type == KNX_SCENE) {
|
||||
// VALUE
|
||||
uint8_t tempvar = knx.data_to_1byte_uint(msg.data);
|
||||
dtostrfd(tempvar,2,tempchar);
|
||||
} else {
|
||||
// VALUE
|
||||
float tempvar = knx.data_to_2byte_float(msg.data);
|
||||
dtostrfd(tempvar,2,tempchar);
|
||||
|
@ -602,6 +612,18 @@ void KNX_CB_Action(message_t const &msg, void *arg)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (chan->type == KNX_SCENE) // KNX RX SCENE SLOT (write command)
|
||||
{
|
||||
if (!toggle_inhibit) {
|
||||
char command[25];
|
||||
// Value received
|
||||
snprintf_P(command, sizeof(command), PSTR("event KNX_SCENE=%s"), tempchar);
|
||||
ExecuteCommand(command, SRC_KNX);
|
||||
if (Settings.flag.knx_enable_enhancement) {
|
||||
toggle_inhibit = TOGGLE_INHIBIT_TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -1054,6 +1076,31 @@ void CmndKnxTxVal(void)
|
|||
}
|
||||
}
|
||||
|
||||
void CmndKnxTxScene(void)
|
||||
{
|
||||
if ( (XdrvMailbox.data_len > 0) && Settings.flag.knx_enabled ) {
|
||||
// XdrvMailbox.payload <- scene number to send
|
||||
uint8_t i = KNX_GA_Search(KNX_SCENE);
|
||||
if ( i != KNX_Empty ) {
|
||||
KNX_addr.value = Settings.knx_GA_addr[i];
|
||||
|
||||
uint8_t tempvar = TextToInt(XdrvMailbox.data);
|
||||
dtostrfd(tempvar,0,XdrvMailbox.data);
|
||||
|
||||
knx.write_1byte_uint(KNX_addr, tempvar);
|
||||
if (Settings.flag.knx_enable_enhancement) {
|
||||
knx.write_1byte_uint(KNX_addr, tempvar);
|
||||
knx.write_1byte_uint(KNX_addr, tempvar);
|
||||
}
|
||||
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d.%d.%d"),
|
||||
device_param_ga[KNX_SCENE-1], XdrvMailbox.data,
|
||||
KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member);
|
||||
ResponseCmndIdxChar (XdrvMailbox.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CmndKnxEnabled(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
|
||||
|
@ -1208,7 +1255,7 @@ bool Xdrv11(uint8_t function)
|
|||
bool result = false;
|
||||
switch (function) {
|
||||
case FUNC_LOOP:
|
||||
if (!global_state.wifi_down) { knx.loop(); } // Process knx events
|
||||
if (!global_state.network_down) { knx.loop(); } // Process knx events
|
||||
break;
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
if (toggle_inhibit) {
|
||||
|
|
|
@ -27,14 +27,14 @@ const char kHAssJsonSensorTypes[] PROGMEM =
|
|||
D_JSON_APPARENT_POWERUSAGE "|Battery|" D_JSON_CURRENT "|" D_JSON_DISTANCE "|" D_JSON_FREQUENCY "|" D_JSON_HUMIDITY "|" D_JSON_ILLUMINANCE "|"
|
||||
D_JSON_MOISTURE "|PB0.3|PB0.5|PB1|PB2.5|PB5|PB10|PM1|PM2.5|PM10|" D_JSON_POWERFACTOR "|" D_JSON_POWERUSAGE "|" D_JSON_TOTAL_START_TIME "|"
|
||||
D_JSON_REACTIVE_POWERUSAGE "|" D_JSON_TODAY "|" D_JSON_TOTAL "|" D_JSON_VOLTAGE "|" D_JSON_WEIGHT "|" D_JSON_YESTERDAY "|"
|
||||
D_JSON_CO2 "|" D_JSON_ECO2 "|" D_JSON_TVOC "|";
|
||||
D_JSON_CO2 "|" D_JSON_ECO2 "|" D_JSON_TVOC "|" D_COLOR_RED "|" D_COLOR_GREEN "|" D_COLOR_BLUE"|" D_CCT "|" D_PROXIMITY "|Ambient|";
|
||||
|
||||
const char kHAssJsonSensorUnits[] PROGMEM =
|
||||
"||||"
|
||||
"VA|%|A|Cm|Hz|%|LX|"
|
||||
"%|ppd|ppd|ppd|ppd|ppd|ppd|µg/m³|µg/m³|µg/m³|Cos φ|W| |"
|
||||
"VAr|kWh|kWh|V|Kg|kWh|"
|
||||
"ppm|ppm|ppb|";
|
||||
"ppm|ppm|ppb|R|G|B|" D_UNIT_KELVIN "| |LX|";
|
||||
|
||||
const char kHAssJsonSensorDevCla[] PROGMEM =
|
||||
"dev_cla\":\"temperature|ic\":\"mdi:weather-rainy|dev_cla\":\"pressure|dev_cla\":\"pressure|"
|
||||
|
@ -42,61 +42,64 @@ const char kHAssJsonSensorDevCla[] PROGMEM =
|
|||
"ic\":\"mdi:cup-water|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|"
|
||||
"ic\":\"mdi:air-filter|ic\":\"mdi:air-filter|ic\":\"mdi:air-filter|ic\":\"mdi:alpha-f-circle-outline|dev_cla\":\"power|ic\":\"mdi:progress-clock|"
|
||||
"dev_cla\":\"power|dev_cla\":\"power|dev_cla\":\"power|ic\":\"mdi:alpha-v-circle-outline|ic\":\"mdi:scale|dev_cla\":\"power|"
|
||||
"ic\":\"mdi:periodic-table-co2|ic\":\"mdi:air-filter|ic\":\"mdi:periodic-table-co2|";
|
||||
"ic\":\"mdi:periodic-table-co2|ic\":\"mdi:air-filter|ic\":\"mdi:periodic-table-co2|"
|
||||
"ic\":\"mdi:palette|ic\":\"mdi:palette|ic\":\"mdi:palette|ic\":\"mdi:temperature-kelvin|ic\":\"mdi:ruler|dev_cla\":\"illuminance|";
|
||||
//"ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|"
|
||||
// List of sensors ready for discovery
|
||||
|
||||
const char HASS_DISCOVER_SENSOR[] PROGMEM =
|
||||
",\"unit_of_meas\":\"%s\",\"%s\"," // unit of measure and class (or icon)
|
||||
"\"frc_upd\":true," // force update for better graph representation
|
||||
"\"val_tpl\":\"{{value_json['%s']['%s']"; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER']['C1']
|
||||
|
||||
const char HASS_DISCOVER_BASE[] PROGMEM =
|
||||
"{\"name\":\"%s\"," // dualr2 1
|
||||
"\"stat_t\":\"%s\"," // stat/dualr2/RESULT (implies "\"optimistic\":\"false\",")
|
||||
"\"avty_t\":\"%s\"," // tele/dualr2/LWT
|
||||
"\"pl_avail\":\"" D_ONLINE "\"," // Online
|
||||
"\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline
|
||||
"{\"name\":\"%s\"," // dualr2 1
|
||||
"\"stat_t\":\"%s\""; // stat/dualr2/RESULT (implies "\"optimistic\":\"false\",")
|
||||
|
||||
const char HASS_DISCOVER_SENSOR[] PROGMEM =
|
||||
",\"unit_of_meas\":\"%s\",\"%s\"," // unit of measure and class (or icon)
|
||||
"\"frc_upd\":true," // force update for better graph representation
|
||||
"\"val_tpl\":\"{{value_json['%s']['%s']"; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER']['C1']
|
||||
|
||||
const char HASS_DISCOVER_SENSOR_LWT[] PROGMEM =
|
||||
",\"avty_t\":\"%s\"," // tele/dualr2/LWT
|
||||
"\"pl_avail\":\"" D_ONLINE "\"," // Online
|
||||
"\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline
|
||||
|
||||
const char HASS_DISCOVER_RELAY[] PROGMEM =
|
||||
",\"cmd_t\":\"%s\"," // cmnd/dualr2/POWER2
|
||||
"\"val_tpl\":\"{{value_json.%s}}\"," // POWER2
|
||||
"\"pl_off\":\"%s\"," // OFF
|
||||
"\"pl_on\":\"%s\""; // ON
|
||||
",\"cmd_t\":\"%s\"," // cmnd/dualr2/POWER2
|
||||
"\"val_tpl\":\"{{value_json.%s}}\"," // POWER2
|
||||
"\"pl_off\":\"%s\"," // OFF
|
||||
"\"pl_on\":\"%s\""; // ON
|
||||
|
||||
const char HASS_DISCOVER_BIN_SWITCH[] PROGMEM =
|
||||
",\"val_tpl\":\"{{value_json.%s}}\"," // STATE
|
||||
"\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work
|
||||
"\"pl_on\":\"%s\"," // ON
|
||||
"\"pl_off\":\"%s\""; // OFF
|
||||
",\"val_tpl\":\"{{value_json.%s}}\"," // STATE
|
||||
"\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work
|
||||
"\"pl_on\":\"%s\"," // ON
|
||||
"\"pl_off\":\"%s\""; // OFF
|
||||
|
||||
const char HASS_DISCOVER_BIN_PIR[] PROGMEM =
|
||||
",\"val_tpl\":\"{{value_json.%s}}\"," // STATE
|
||||
"\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work
|
||||
"\"pl_on\":\"%s\"," // ON
|
||||
"\"off_dly\":1"; // Switchmode13 and Switchmode14 doesn't transmit an OFF state.
|
||||
",\"val_tpl\":\"{{value_json.%s}}\"," // STATE
|
||||
"\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work
|
||||
"\"pl_on\":\"%s\"," // ON
|
||||
"\"off_dly\":1"; // Switchmode13 and Switchmode14 doesn't transmit an OFF state.
|
||||
|
||||
const char HASS_DISCOVER_BASE_LIGHT[] PROGMEM =
|
||||
",\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer
|
||||
"\"bri_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||
"\"bri_scl\":100," // 100%
|
||||
"\"on_cmd_type\":\"%s\"," // power on (first), power on (last), no power on (brightness)
|
||||
",\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer
|
||||
"\"bri_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||
"\"bri_scl\":100," // 100%
|
||||
"\"on_cmd_type\":\"%s\"," // power on (first), power on (last), no power on (brightness)
|
||||
"\"bri_val_tpl\":\"{{value_json.%s}}\"";
|
||||
|
||||
const char HASS_DISCOVER_LIGHT_COLOR[] PROGMEM =
|
||||
",\"rgb_cmd_t\":\"%s2\"," // cmnd/led2/Color2
|
||||
"\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||
",\"rgb_cmd_t\":\"%s2\"," // cmnd/led2/Color2
|
||||
"\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||
"\"rgb_val_tpl\":\"{{value_json." D_CMND_COLOR ".split(',')[0:3]|join(',')}}\"";
|
||||
|
||||
const char HASS_DISCOVER_LIGHT_WHITE[] PROGMEM =
|
||||
",\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White
|
||||
"\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||
",\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White
|
||||
"\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||
"\"whit_val_scl\":100,"
|
||||
"\"whit_val_tpl\":\"{{value_json.Channel[3]}}\"";
|
||||
|
||||
const char HASS_DISCOVER_LIGHT_CT[] PROGMEM =
|
||||
",\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT
|
||||
"\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||
",\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT
|
||||
"\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT
|
||||
"\"clr_temp_val_tpl\":\"{{value_json." D_CMND_COLORTEMPERATURE "}}\"";
|
||||
|
||||
const char HASS_DISCOVER_LIGHT_SCHEME[] PROGMEM =
|
||||
|
@ -141,7 +144,7 @@ const char kHAssTriggerStringButtons[] PROGMEM =
|
|||
"|SINGLE|DOUBLE|TRIPLE|QUAD|PENTA|HOLD|";
|
||||
|
||||
const char kHAssError1[] PROGMEM =
|
||||
"HASS: MQTT discovery failed due to too long topic or friendly name. Please shorten topic and/or friendly name. Failed to format";
|
||||
"HASS: MQTT discovery failed due to too long topic or device/friendly name. Please shorten topic and/or device/friendly name. Failed to format";
|
||||
|
||||
const char kHAssError2[] PROGMEM =
|
||||
"HASS: The configuration of the Relays is wrong, there is a Light that is using an index higher than the number of the validated relay.\n "
|
||||
|
@ -195,13 +198,22 @@ void HAssAnnounceRelayLight(void)
|
|||
bool ct_light = false; // Controls a CT Light when SetOption37 is >= 128
|
||||
bool wt_light = false; // Controls a White Light when SetOption37 is >= 128
|
||||
bool err_flag = false; // When true it blocks the creation of entities if the order of the Relays is not correct to avoid issue with Lights
|
||||
bool TuyaMod = false; // Controls Tuya MCU modules
|
||||
bool PwmMod = false; // Controls PWM_DIMMER module
|
||||
bool FanMod = false; // Controls SONOFF_IFAN0X modules
|
||||
|
||||
uint8_t dimmer = 1;
|
||||
uint8_t valid_relay = 0;
|
||||
uint8_t max_lights = 1;
|
||||
uint8_t TuyaRel = 0;
|
||||
uint8_t TuyaRelInv = 0;
|
||||
uint8_t TuyaDim = 0;
|
||||
|
||||
#ifdef ESP8266
|
||||
if (PWM_DIMMER == my_module_type) { PwmMod = true; }
|
||||
if (PWM_DIMMER == my_module_type ) { PwmMod = true; } //
|
||||
if (SONOFF_IFAN02 == my_module_type || SONOFF_IFAN03 == my_module_type) { FanMod = true; }
|
||||
if (SONOFF_DUAL == my_module_type) { valid_relay = 2; }
|
||||
if (TUYA_DIMMER == my_module_type || SK03_TUYA == my_module_type) { TuyaMod = true; }
|
||||
#endif //ESP8266
|
||||
|
||||
// If there is a special Light to be enabled and managed with SetOption68 or SetOption37 >= 128, Discovery calculates the maximum number of entities to be generated in advance
|
||||
|
@ -209,17 +221,21 @@ void HAssAnnounceRelayLight(void)
|
|||
if (PwmMulti) { max_lights = Light.subtype; }
|
||||
|
||||
if (!LightControl) {
|
||||
ind_light = 1;
|
||||
ind_light = true;
|
||||
if (!PwmMulti) { max_lights = 2;}
|
||||
}
|
||||
|
||||
// Lights types: 0 = LST_NONE / 1 = LST_SINGLE / 2 = LST_COLDWARM / 3 = LST_RGB / 4 = LST_RGBW / 5 = LST_RGBCW
|
||||
|
||||
for (uint32_t i = 1; i <= MAX_RELAYS; i++)
|
||||
{
|
||||
bool RelayX = PinUsed(GPIO_REL1 +i-1);
|
||||
is_topic_light = Settings.flag.hass_light && RelayX || light_type && !RelayX || PwmMod; // SetOption30 - Enforce HAss autodiscovery as light
|
||||
|
||||
#ifdef USE_TUYA_MCU
|
||||
TuyaRel = TuyaGetDpId((TUYA_MCU_FUNC_REL1+ i-1) + active_device - 1);
|
||||
TuyaRelInv = TuyaGetDpId((TUYA_MCU_FUNC_REL1_INV+ i-1) + active_device - 1);
|
||||
TuyaDim = TuyaGetDpId((TUYA_MCU_FUNC_DIMMER) + active_device - 1);
|
||||
#endif //USE_TUYA_MCU
|
||||
|
||||
bool RelayX = PinUsed(GPIO_REL1 +i-1) || (valid_relay >= i) || (TuyaRel > 0 && TuyaMod) || (TuyaRelInv > 0 && TuyaMod); // Check if the gpio is configured as Relay or force it for Sonoff DUAL R1 with MCU and Tuya MCU
|
||||
is_topic_light = Settings.flag.hass_light && RelayX || light_type && !RelayX || PwmMod || (TuyaDim > 0 && TuyaMod); // SetOption30 - Enforce HAss autodiscovery as light
|
||||
mqtt_data[0] = '\0'; // Clear retained message
|
||||
|
||||
// Clear "other" topic first in case the device has been reconfigured from light to switch or vice versa
|
||||
|
@ -255,13 +271,14 @@ void HAssAnnounceRelayLight(void)
|
|||
GetTopic_P(command_topic, CMND, mqtt_topic, value_template);
|
||||
GetTopic_P(state_topic, TELE, mqtt_topic, D_RSLT_STATE);
|
||||
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
|
||||
Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic);
|
||||
Response_P(HASS_DISCOVER_BASE, name, state_topic);
|
||||
TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic);
|
||||
TryResponseAppend_P(HASS_DISCOVER_RELAY, command_topic, value_template, SettingsText(SET_STATE_TXT1), SettingsText(SET_STATE_TXT2));
|
||||
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId());
|
||||
|
||||
#ifdef USE_LIGHT
|
||||
if (i >= Light.device) {
|
||||
if (!RelayX || PwmMod) {
|
||||
if (!RelayX || PwmMod || (TuyaDim > 0 && TuyaMod)) {
|
||||
char *brightness_command_topic = stemp1;
|
||||
strncpy_P(stemp3, Settings.flag.not_power_linked ? PSTR("last") : PSTR("brightness"), sizeof(stemp3)); // SetOption20 - Control power in relation to Dimmer/Color/Ct changes
|
||||
char channel_num[9];
|
||||
|
@ -411,6 +428,14 @@ void HAssAnnouncerBinSensors(uint8_t device, uint8_t present, uint8_t dual, uint
|
|||
TryResponseAppend_P(HASS_DISCOVER_BIN_PIR, PSTR(D_RSLT_STATE), SettingsText(SET_STATE_TXT2));
|
||||
}
|
||||
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId());
|
||||
#ifdef DEEPSLEEP_LWT_HA_DISCOVERY
|
||||
TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic);
|
||||
#else
|
||||
if (Settings.deepsleep == 0)
|
||||
{
|
||||
TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic);
|
||||
}
|
||||
#endif //DEEPSLEEP_LWT_HA_DISCOVERY
|
||||
TryResponseAppend_P(PSTR("}"));
|
||||
}
|
||||
}
|
||||
|
@ -505,7 +530,7 @@ void HAssAnnounceButtons(void)
|
|||
{
|
||||
button_present = 1;
|
||||
} else
|
||||
#endif
|
||||
#endif // ESP8266
|
||||
{
|
||||
if (PinUsed(GPIO_KEY1, button_index)) {
|
||||
button_present = 1;
|
||||
|
@ -557,12 +582,21 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const
|
|||
char prefix[TOPSZ];
|
||||
char *state_topic = stemp1;
|
||||
char *availability_topic = stemp2;
|
||||
//bool LwtSensor = MQTT_LWT_DISCOVERY;
|
||||
|
||||
GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_SENSOR));
|
||||
snprintf_P(name, sizeof(name), PSTR("%s %s %s"), SettingsText(SET_DEVICENAME), sensorname, MultiSubName);
|
||||
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
|
||||
|
||||
Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic);
|
||||
Response_P(HASS_DISCOVER_BASE, name, state_topic);
|
||||
#ifdef DEEPSLEEP_LWT_HA_DISCOVERY
|
||||
TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic);
|
||||
#else
|
||||
if (Settings.deepsleep == 0)
|
||||
{
|
||||
TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic);
|
||||
}
|
||||
#endif //DEEPSLEEP_LWT_HA_DISCOVERY
|
||||
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId());
|
||||
|
||||
|
||||
|
@ -629,8 +663,8 @@ void HAssAnnounceSensors(void)
|
|||
sensordata[0] = '{';
|
||||
snprintf_P(sensordata, sizeof(sensordata), PSTR("%s}"), sensordata); // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}}
|
||||
// USE THE FOLLOWING LINE TO TEST JSON
|
||||
//snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"HX711\":{\"Weight\":[22,34,1023.4]}}"));
|
||||
|
||||
//snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"APDS9960\":{\"Red\":282,\"Green\":252,\"Blue\":196,\"Ambient\":169,\"CCT\":4217,\"Proximity\":9}}"));
|
||||
//snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"ENERGY\":{\"TotalStartTime\":\"2018-11-23T15:33:47\",\"Total\":0.017,\"TotalTariff\":[0.000,0.017],\"Yesterday\":0.000,\"Today\":0.002,\"ExportActive\":0.000,\"ExportTariff\":[0.000,0.000],\"Period\":0.00,\"Power\":0.00,\"ApparentPower\":7.84,\"ReactivePower\":-7.21,\"Factor\":0.39,\"Frequency\":50.0,\"Voltage\":234.31,\"Current\":0.039,\"ImportActive\":12.580,\"ImportReactive\":0.002,\"ExportReactive\":39.131,\"PhaseAngle\":290.45}}"));
|
||||
|
||||
StaticJsonBuffer<500> jsonBuffer;
|
||||
JsonObject &root = jsonBuffer.parseObject(sensordata);
|
||||
|
@ -703,7 +737,8 @@ void HAssAnnounceDeviceInfoAndStatusSensor(void)
|
|||
GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_HASS_STATE));
|
||||
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
|
||||
|
||||
Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic);
|
||||
Response_P(HASS_DISCOVER_BASE, name, state_topic);
|
||||
TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic);
|
||||
TryResponseAppend_P(HASS_DISCOVER_SENSOR_HASS_STATUS, state_topic);
|
||||
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO, unique_id, ESP_getChipId(), SettingsText(SET_DEVICENAME),
|
||||
ModuleName().c_str(), my_version, my_image);
|
||||
|
@ -812,7 +847,6 @@ void HAssAnyKey(void)
|
|||
bool Xdrv12(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (Settings.flag.mqtt_enabled)
|
||||
{ // SetOption3 - Enable MQTT
|
||||
switch (function)
|
||||
|
@ -844,10 +878,13 @@ bool Xdrv12(uint8_t function)
|
|||
case FUNC_MQTT_INIT:
|
||||
hass_mode = 0; // Discovery only if Settings.flag.hass_discovery is set
|
||||
hass_init_step = 2; // Delayed discovery
|
||||
// if (!Settings.flag.hass_discovery) {
|
||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR("MQT: homeassistant/49A3BC/Discovery = {\"dev\":{\"ids\":[\"49A3BC\"]},\"cmd_t\":\"cmnd/test1/\",\"Discovery\":0}"));
|
||||
// }
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_HOME_ASSISTANT
|
||||
#endif // USE_HOME_ASSISTANT
|
|
@ -1013,14 +1013,14 @@ void DisplayLogBufferInit(void)
|
|||
snprintf_P(buffer, sizeof(buffer), PSTR("Display mode %d"), Settings.display_mode);
|
||||
DisplayLogBufferAdd(buffer);
|
||||
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_CMND_HOSTNAME " %s"), my_hostname);
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_CMND_HOSTNAME " %s"), NetworkHostname());
|
||||
DisplayLogBufferAdd(buffer);
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_SSID " %s"), SettingsText(SET_STASSID1 + Settings.sta_active));
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), NetworkMacAddress().c_str());
|
||||
DisplayLogBufferAdd(buffer);
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), WiFi.macAddress().c_str());
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR("IP %s"), NetworkAddress().toString().c_str());
|
||||
DisplayLogBufferAdd(buffer);
|
||||
if (!global_state.wifi_down) {
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR("IP %s"), WiFi.localIP().toString().c_str());
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_SSID " %s"), SettingsText(SET_STASSID1 + Settings.sta_active));
|
||||
DisplayLogBufferAdd(buffer);
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_RSSI " %d%%"), WifiGetRssiAsQuality(WiFi.RSSI()));
|
||||
DisplayLogBufferAdd(buffer);
|
||||
|
|
|
@ -19,6 +19,13 @@
|
|||
|
||||
#ifdef USE_ZIGBEE
|
||||
|
||||
#if defined(USE_ZIGBEE_ZNP) && defined(USE_ZIGBEE_EZSP)
|
||||
#error "#define USE_ZIGBEE_ZNP and #define USE_ZIGBEE_EZSP are mutually incompatible"
|
||||
#endif
|
||||
#if !defined(USE_ZIGBEE_ZNP) && !defined(USE_ZIGBEE_EZSP)
|
||||
#error "You must select one of: #define USE_ZIGBEE_ZNP or #define USE_ZIGBEE_EZSP"
|
||||
#endif
|
||||
|
||||
#define OCCUPANCY "Occupancy" // global define for Aqara
|
||||
|
||||
typedef uint64_t Z_IEEEAddress;
|
||||
|
@ -26,6 +33,7 @@ typedef uint16_t Z_ShortAddress;
|
|||
|
||||
const uint16_t BAD_SHORTADDR = 0xFFFE;
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
enum ZnpCommandType {
|
||||
Z_POLL = 0x00,
|
||||
Z_SREQ = 0x20,
|
||||
|
@ -45,6 +53,7 @@ enum ZnpSubsystem {
|
|||
Z_DEBUG = 0x08,
|
||||
Z_APP = 0x09
|
||||
};
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
// Commands in the SYS subsystem
|
||||
enum SysCommand {
|
||||
|
|
|
@ -168,6 +168,8 @@ SBuffer *zigbee_buffer = nullptr;
|
|||
|
||||
#define USE_ZIGBEE_CHANNEL_MASK (1 << (USE_ZIGBEE_CHANNEL))
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
|
||||
// ZBS_* Zigbee Send
|
||||
// ZBR_* Zigbee Recv
|
||||
ZBM(ZBS_RESET, Z_AREQ | Z_SYS, SYS_RESET, 0x00 ) // 410001 SYS_RESET_REQ Hardware reset
|
||||
|
@ -611,6 +613,30 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
|
|||
ZI_STOP(ZIGBEE_LABEL_ABORT)
|
||||
};
|
||||
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
|
||||
// Update the relevant commands with Settings
|
||||
void Z_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_panid, uint64_t zb_precfgkey_l, uint64_t zb_precfgkey_h) {
|
||||
}
|
||||
|
||||
|
||||
static const Zigbee_Instruction zb_prog[] PROGMEM = {
|
||||
ZI_LABEL(0)
|
||||
ZI_NOOP()
|
||||
ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT)
|
||||
ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT)
|
||||
// ZI_ON_RECV_UNEXPECTED(&Z_Recv_Default)
|
||||
// ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize
|
||||
|
||||
ZI_LABEL(ZIGBEE_LABEL_MAIN_LOOP)
|
||||
ZI_WAIT_FOREVER()
|
||||
ZI_GOTO(ZIGBEE_LABEL_READY)
|
||||
};
|
||||
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
|
||||
uint8_t ZigbeeGetInstructionSize(uint8_t instr) { // in Zigbee_Instruction lines (words)
|
||||
if (instr >= ZGB_INSTR_12_BYTES) {
|
||||
return 3;
|
||||
|
@ -770,7 +796,9 @@ void ZigbeeStateMachine_Run(void) {
|
|||
}
|
||||
break;
|
||||
case ZGB_INSTR_SEND:
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
ZigbeeZNPSend((uint8_t*) cur_ptr1, cur_d8 /* len */);
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
break;
|
||||
case ZGB_INSTR_WAIT_UNTIL:
|
||||
zigbee.recv_until = true; // and reuse ZGB_INSTR_WAIT_RECV
|
||||
|
|
|
@ -552,6 +552,7 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
/*********************************************************************************************\
|
||||
* Send specific ZNP messages
|
||||
\*********************************************************************************************/
|
||||
|
@ -589,6 +590,32 @@ void Z_SendAFInfoRequest(uint16_t shortaddr) {
|
|||
ZigbeeZNPSend(AFInfoReq, sizeof(AFInfoReq));
|
||||
}
|
||||
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
/*********************************************************************************************\
|
||||
* Send specific EZS¨ messages
|
||||
\*********************************************************************************************/
|
||||
|
||||
//
|
||||
// Send ZDO_IEEE_ADDR_REQ request to get IEEE long address
|
||||
//
|
||||
void Z_SendIEEEAddrReq(uint16_t shortaddr) {
|
||||
}
|
||||
|
||||
//
|
||||
// Send ACTIVE_EP_REQ to collect active endpoints for this address
|
||||
//
|
||||
void Z_SendActiveEpReq(uint16_t shortaddr) {
|
||||
}
|
||||
|
||||
//
|
||||
// Send AF Info Request
|
||||
//
|
||||
void Z_SendAFInfoRequest(uint16_t shortaddr) {
|
||||
}
|
||||
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Callbacks
|
||||
|
@ -718,6 +745,8 @@ typedef struct Z_Dispatcher {
|
|||
ZB_RecvMsgFunc func;
|
||||
} Z_Dispatcher;
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
|
||||
// Ffilters based on ZNP frames
|
||||
ZBM(AREQ_AF_DATA_CONFIRM, Z_AREQ | Z_AF, AF_DATA_CONFIRM) // 4480
|
||||
ZBM(AREQ_AF_INCOMING_MESSAGE, Z_AREQ | Z_AF, AF_INCOMING_MSG) // 4481
|
||||
|
@ -767,6 +796,8 @@ int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) {
|
|||
}
|
||||
}
|
||||
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Functions called by State Machine
|
||||
\*********************************************************************************************/
|
||||
|
@ -835,8 +866,8 @@ void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const
|
|||
// responder
|
||||
switch (cluster) {
|
||||
case 0x0000:
|
||||
if (HasKeyCaseInsensitive(json, PSTR("ModelId"))) { json_out[F("ModelId")] = F("Tasmota Z2T"); }
|
||||
if (HasKeyCaseInsensitive(json, PSTR("Manufacturer"))) { json_out[F("Manufacturer")] = F("Tasmota"); }
|
||||
if (HasKeyCaseInsensitive(json, PSTR("ModelId"))) { json_out[F("ModelId")] = F(USE_ZIGBEE_MODELID); }
|
||||
if (HasKeyCaseInsensitive(json, PSTR("Manufacturer"))) { json_out[F("Manufacturer")] = F(USE_ZIGBEE_MANUFACTURER); }
|
||||
break;
|
||||
#ifdef USE_LIGHT
|
||||
case 0x0006:
|
||||
|
|
|
@ -21,18 +21,32 @@
|
|||
|
||||
#define XDRV_23 23
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
const uint32_t ZIGBEE_BUFFER_SIZE = 256; // Max ZNP frame is SOF+LEN+CMD1+CMD2+250+FCS = 255
|
||||
const uint8_t ZIGBEE_SOF = 0xFE;
|
||||
const uint8_t ZIGBEE_SOF_ALT = 0xFF;
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
const uint32_t ZIGBEE_BUFFER_SIZE = 256;
|
||||
const uint8_t ZIGBEE_EZSP_CANCEL = 0x1A; // cancel byte
|
||||
const uint8_t ZIGBEE_EZSP_EOF = 0x7E; // end of frame
|
||||
const uint8_t ZIGBEE_EZSP_ESCAPE = 0x7D; // escape byte
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
TasmotaSerial *ZigbeeSerial = nullptr;
|
||||
|
||||
|
||||
const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
|
||||
D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEE_PERMITJOIN "|"
|
||||
D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|"
|
||||
D_CMND_ZIGBEE_PROBE "|" D_CMND_ZIGBEEZNPRECEIVE "|"
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEEZNPRECEIVE "|"
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
D_CMND_ZIGBEE_EZSP_SEND "|" D_CMND_ZIGBEE_EZSP_RECEIVE "|"
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
D_CMND_ZIGBEE_PERMITJOIN "|"
|
||||
D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|" D_CMND_ZIGBEE_PROBE "|"
|
||||
D_CMND_ZIGBEE_FORGET "|" D_CMND_ZIGBEE_SAVE "|" D_CMND_ZIGBEE_NAME "|"
|
||||
D_CMND_ZIGBEE_BIND "|" D_CMND_ZIGBEE_UNBIND "|" D_CMND_ZIGBEE_PING "|" D_CMND_ZIGBEE_MODELID "|"
|
||||
D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|"
|
||||
|
@ -40,9 +54,14 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
|
|||
;
|
||||
|
||||
void (* const ZigbeeCommand[])(void) PROGMEM = {
|
||||
&CmndZbZNPSend, &CmndZbPermitJoin,
|
||||
&CmndZbStatus, &CmndZbReset, &CmndZbSend,
|
||||
&CmndZbProbe, &CmndZbZNPReceive,
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
&CmndZbZNPSend, &CmndZbZNPReceive,
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
&CmndZbEZSPSend, &CmndZbEZSPReceive,
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
&CmndZbPermitJoin,
|
||||
&CmndZbStatus, &CmndZbReset, &CmndZbSend, &CmndZbProbe,
|
||||
&CmndZbForget, &CmndZbSave, &CmndZbName,
|
||||
&CmndZbBind, &CmndZbUnbind, &CmndZbPing, &CmndZbModelId,
|
||||
&CmndZbLight, &CmndZbRestore, &CmndZbBindState,
|
||||
|
@ -52,11 +71,12 @@ void (* const ZigbeeCommand[])(void) PROGMEM = {
|
|||
//
|
||||
// Called at event loop, checks for incoming data from the CC2530
|
||||
//
|
||||
void ZigbeeInputLoop(void)
|
||||
{
|
||||
static uint32_t zigbee_polling_window = 0;
|
||||
void ZigbeeInputLoop(void) {
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte
|
||||
static uint8_t fcs = ZIGBEE_SOF;
|
||||
static uint32_t zigbee_frame_len = 5; // minimal zigbee frame lenght, will be updated when buf[1] is read
|
||||
static uint32_t zigbee_frame_len = 5; // minimal zigbee frame length, will be updated when buf[1] is read
|
||||
// Receive only valid ZNP frames:
|
||||
// 00 - SOF = 0xFE
|
||||
// 01 - Length of Data Field - 0..250
|
||||
|
@ -140,6 +160,127 @@ void ZigbeeInputLoop(void)
|
|||
}
|
||||
zigbee_buffer->setLen(0); // empty buffer
|
||||
}
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte
|
||||
bool escape = false; // was the previous byte an escape?
|
||||
bool frame_complete = false; // frame is ready and complete
|
||||
// Receive only valid EZSP frames:
|
||||
// 1A - Cancel - cancel all previous bytes
|
||||
// 7D - Escape byte - following byte is escaped
|
||||
// 7E - end of frame
|
||||
|
||||
while (ZigbeeSerial->available()) {
|
||||
yield();
|
||||
uint8_t zigbee_in_byte = ZigbeeSerial->read();
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x%02X len=%d"), zigbee_in_byte, zigbee_buffer->len());
|
||||
|
||||
// if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized
|
||||
// escape = false;
|
||||
// frame_complete = false;
|
||||
// }
|
||||
|
||||
if ((0x11 == zigbee_in_byte) || (0x13 == zigbee_in_byte)) {
|
||||
continue; // ignore reserved bytes XON/XOFF
|
||||
}
|
||||
|
||||
if (ZIGBEE_EZSP_ESCAPE == zigbee_in_byte) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Escape byte received"));
|
||||
escape = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ZIGBEE_EZSP_CANCEL == zigbee_in_byte) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x1A, cancel byte received, discarding %d bytes"), zigbee_buffer->len());
|
||||
zigbee_buffer->setLen(0); // empty buffer
|
||||
escape = false;
|
||||
frame_complete = false;
|
||||
continue; // re-loop
|
||||
}
|
||||
|
||||
if (ZIGBEE_EZSP_EOF == zigbee_in_byte) {
|
||||
// end of frame
|
||||
frame_complete = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (zigbee_buffer->len() < ZIGBEE_BUFFER_SIZE) {
|
||||
if (escape) {
|
||||
// invert bit 5
|
||||
zigbee_in_byte ^= 0x20;
|
||||
escape = false;
|
||||
}
|
||||
|
||||
zigbee_buffer->add8(zigbee_in_byte);
|
||||
zigbee_polling_window = millis(); // Wait for more data
|
||||
} // adding bytes
|
||||
} // while (ZigbeeSerial->available())
|
||||
|
||||
uint32_t frame_len = zigbee_buffer->len();
|
||||
if (frame_complete || (frame_len && (millis() > (zigbee_polling_window + ZIGBEE_POLLING)))) {
|
||||
char hex_char[frame_len * 2 + 2];
|
||||
ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char));
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric());
|
||||
if ((frame_complete) && (frame_len >= 3)) {
|
||||
// frame received and has at least 3 bytes (without EOF), checking CRC
|
||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": received raw frame %s"), hex_char);
|
||||
uint16_t crc = 0xFFFF; // frame CRC
|
||||
// compute CRC
|
||||
for (uint32_t i=0; i<frame_len-2; i++) {
|
||||
crc = crc ^ ((uint16_t)zigbee_buffer->get8(i) << 8);
|
||||
for (uint32_t i=0; i<8; i++) {
|
||||
if (crc & 0x8000) {
|
||||
crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard
|
||||
} else {
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t crc_received = zigbee_buffer->get8(frame_len - 2) << 8 | zigbee_buffer->get8(frame_len - 1);
|
||||
// remove 2 last bytes
|
||||
|
||||
if (crc_received != crc) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": bad crc (received 0x%04X, computed 0x%04X) %s"), crc_received, crc, hex_char);
|
||||
} else {
|
||||
// copy buffer
|
||||
SBuffer ezsp_buffer = zigbee_buffer->subBuffer(0, frame_len - 2); // CRC
|
||||
|
||||
// CRC is correct, apply de-stuffing if DATA frame
|
||||
if (0 == (ezsp_buffer.get8(0) & 0x80)) {
|
||||
// DATA frame
|
||||
uint8_t rand = 0x42;
|
||||
for (uint32_t i=1; i<ezsp_buffer.len(); i++) {
|
||||
ezsp_buffer.set8(i, ezsp_buffer.get8(i) ^ rand);
|
||||
if (rand & 1) { rand = (rand >> 1) ^ 0xB8; }
|
||||
else { rand = (rand >> 1); }
|
||||
}
|
||||
}
|
||||
|
||||
ToHex_P((unsigned char*)ezsp_buffer.getBuffer(), ezsp_buffer.len(), hex_char, sizeof(hex_char));
|
||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "\":\"%s\"}"), hex_char);
|
||||
if (Settings.flag3.tuya_serial_mqtt_publish) {
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR));
|
||||
XdrvRulesProcess();
|
||||
} else {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable
|
||||
}
|
||||
// now process the message
|
||||
ZigbeeProcessInput(ezsp_buffer);
|
||||
}
|
||||
} else {
|
||||
// the buffer timed-out, print error and discard
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %d"), hex_char);
|
||||
}
|
||||
zigbee_buffer->setLen(0); // empty buffer
|
||||
escape = false;
|
||||
frame_complete = false;
|
||||
}
|
||||
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
@ -201,15 +342,20 @@ uint32_t strToUInt(const JsonVariant &val) {
|
|||
return 0; // couldn't parse anything
|
||||
}
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
// Do a factory reset of the CC2530
|
||||
const unsigned char ZIGBEE_FACTORY_RESET[] PROGMEM =
|
||||
{ Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x01 /* STARTOPT_CLEAR_CONFIG */};
|
||||
//"2605030101"; // Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 len, 0x01 STARTOPT_CLEAR_CONFIG
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
void CmndZbReset(void) {
|
||||
if (ZigbeeSerial) {
|
||||
switch (XdrvMailbox.payload) {
|
||||
case 1:
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
ZigbeeZNPSend(ZIGBEE_FACTORY_RESET, sizeof(ZIGBEE_FACTORY_RESET));
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
eraseZigbeeDevices();
|
||||
restart_flag = 2;
|
||||
ResponseCmndChar_P(PSTR(D_JSON_ZIGBEE_CC2530 " " D_JSON_RESET_AND_RESTARTING));
|
||||
|
@ -220,6 +366,38 @@ void CmndZbReset(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
|
||||
void ZigbeeZNPSend(const uint8_t *msg, size_t len) {
|
||||
if ((len < 2) || (len > 252)) {
|
||||
// abort, message cannot be less than 2 bytes for CMD1 and CMD2
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEEZNPSENT ": bad message len %d"), len);
|
||||
return;
|
||||
}
|
||||
uint8_t data_len = len - 2; // removing CMD1 and CMD2
|
||||
|
||||
if (ZigbeeSerial) {
|
||||
uint8_t fcs = data_len;
|
||||
|
||||
ZigbeeSerial->write(ZIGBEE_SOF); // 0xFE
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend SOF %02X"), ZIGBEE_SOF);
|
||||
ZigbeeSerial->write(data_len);
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend LEN %02X"), data_len);
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
uint8_t b = pgm_read_byte(msg + i);
|
||||
ZigbeeSerial->write(b);
|
||||
fcs ^= b;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend byt %02X"), b);
|
||||
}
|
||||
ZigbeeSerial->write(fcs); // finally send fcs checksum byte
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs);
|
||||
}
|
||||
// Now send a MQTT message to report the sent message
|
||||
char hex_char[(len * 2) + 2];
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"),
|
||||
ToHex_P(msg, len, hex_char, sizeof(hex_char)));
|
||||
}
|
||||
|
||||
//
|
||||
// Same code for `ZbZNPSend` and `ZbZNPReceive`
|
||||
// building the complete message (intro, length)
|
||||
|
@ -264,36 +442,138 @@ void CmndZbZNPSend(void)
|
|||
CmndZbZNPSendOrReceive(true);
|
||||
}
|
||||
|
||||
void ZigbeeZNPSend(const uint8_t *msg, size_t len) {
|
||||
if ((len < 2) || (len > 252)) {
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
|
||||
// internal function to output a byte, and escape it (stuffing) if needed
|
||||
void ZigbeeEZSPSend_Out(uint8_t out_byte) {
|
||||
switch (out_byte) {
|
||||
case 0x7E: // Flag byte
|
||||
case 0x11: // XON
|
||||
case 0x13: // XOFF
|
||||
case 0x18: // Substitute byte
|
||||
case 0x1A: // Cancel byte
|
||||
case 0x7D: // Escape byte
|
||||
ZigbeeSerial->write(ZIGBEE_EZSP_ESCAPE); // send Escape byte 0x7D
|
||||
ZigbeeSerial->write(out_byte ^ 0x20); // send with bit 5 inverted
|
||||
break;
|
||||
default:
|
||||
ZigbeeSerial->write(out_byte); // send unchanged
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Send low-level EZSP frames
|
||||
//
|
||||
// The frame should contain the Control Byte and Data Field
|
||||
// The frame shouldn't be escaped, nor randomized
|
||||
//
|
||||
// Before sending:
|
||||
// - send Cancel byte (0x1A) if requested
|
||||
// - randomize Data Field if DATA Frame
|
||||
// - compute CRC16
|
||||
// - escape (stuff) reserved bytes
|
||||
// - add EOF (0x7E)
|
||||
// - send frame
|
||||
// send_cancel: should we first send a EZSP_CANCEL (0x1A) before the message to clear any leftover
|
||||
void ZigbeeEZSPSend(const uint8_t *msg, size_t len, bool send_cancel = false) {
|
||||
if ((len < 1) || (len > 252)) {
|
||||
// abort, message cannot be less than 2 bytes for CMD1 and CMD2
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEEZNPSENT ": bad message len %d"), len);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEE_EZSP_SENT ": bad message len %d"), len);
|
||||
return;
|
||||
}
|
||||
uint8_t data_len = len - 2; // removing CMD1 and CMD2
|
||||
|
||||
if (ZigbeeSerial) {
|
||||
uint8_t fcs = data_len;
|
||||
if (send_cancel) {
|
||||
ZigbeeSerial->write(ZIGBEE_EZSP_CANCEL); // 0x1A
|
||||
}
|
||||
|
||||
ZigbeeSerial->write(ZIGBEE_SOF); // 0xFE
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend SOF %02X"), ZIGBEE_SOF);
|
||||
ZigbeeSerial->write(data_len);
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend LEN %02X"), data_len);
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
uint8_t b = pgm_read_byte(msg + i);
|
||||
ZigbeeSerial->write(b);
|
||||
fcs ^= b;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend byt %02X"), b);
|
||||
}
|
||||
ZigbeeSerial->write(fcs); // finally send fcs checksum byte
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs);
|
||||
bool data_frame = (0 == (msg[0] & 0x80));
|
||||
uint8_t rand = 0x42; // pseudo-randomizer initial value
|
||||
uint16_t crc = 0xFFFF; // CRC16 CCITT initialization
|
||||
|
||||
for (uint32_t i=0; i<len; i++) {
|
||||
uint8_t out_byte = msg[i];
|
||||
|
||||
// apply randomization if DATA field
|
||||
if (data_frame && (i > 0)) {
|
||||
out_byte ^= rand;
|
||||
if (rand & 1) { rand = (rand >> 1) ^ 0xB8; }
|
||||
else { rand = (rand >> 1); }
|
||||
}
|
||||
|
||||
// compute CRC
|
||||
crc = crc ^ ((uint16_t)out_byte << 8);
|
||||
for (uint32_t i=0; i<8; i++) {
|
||||
if (crc & 0x8000) {
|
||||
crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard
|
||||
} else {
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// output byte
|
||||
ZigbeeEZSPSend_Out(out_byte);
|
||||
}
|
||||
// send CRC16 in big-endian
|
||||
ZigbeeEZSPSend_Out(crc >> 8);
|
||||
ZigbeeEZSPSend_Out(crc & 0xFF);
|
||||
|
||||
// finally send End of Frame
|
||||
ZigbeeSerial->write(ZIGBEE_EZSP_EOF); // 0x1A
|
||||
}
|
||||
// Now send a MQTT message to report the sent message
|
||||
char hex_char[(len * 2) + 2];
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"),
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT " %s"),
|
||||
ToHex_P(msg, len, hex_char, sizeof(hex_char)));
|
||||
}
|
||||
|
||||
//
|
||||
// Same code for `ZbZNPSend` and `ZbZNPReceive`
|
||||
// building the complete message (intro, length)
|
||||
//
|
||||
void CmndZbEZSPSendOrReceive(bool send)
|
||||
{
|
||||
if (ZigbeeSerial && (XdrvMailbox.data_len > 0)) {
|
||||
uint8_t code;
|
||||
|
||||
char *codes = RemoveSpace(XdrvMailbox.data);
|
||||
int32_t size = strlen(XdrvMailbox.data);
|
||||
|
||||
SBuffer buf((size+1)/2);
|
||||
|
||||
while (size > 1) {
|
||||
char stemp[3];
|
||||
strlcpy(stemp, codes, sizeof(stemp));
|
||||
code = strtol(stemp, nullptr, 16);
|
||||
buf.add8(code);
|
||||
size -= 2;
|
||||
codes += 2;
|
||||
}
|
||||
if (send) {
|
||||
// Command was `ZbEZSPSend`
|
||||
ZigbeeEZSPSend(buf.getBuffer(), buf.len());
|
||||
} else {
|
||||
// Command was `ZbEZSPReceive`
|
||||
ZigbeeProcessInput(buf);
|
||||
}
|
||||
}
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
// For debug purposes only, simulates a message received
|
||||
void CmndZbEZSPReceive(void)
|
||||
{
|
||||
CmndZbEZSPSendOrReceive(false);
|
||||
}
|
||||
|
||||
void CmndZbEZSPSend(void)
|
||||
{
|
||||
CmndZbEZSPSendOrReceive(true);
|
||||
}
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
|
||||
//
|
||||
// Internal function, send the low-level frame
|
||||
// Input:
|
||||
|
@ -311,6 +591,7 @@ void ZigbeeZNPSend(const uint8_t *msg, size_t len) {
|
|||
//
|
||||
void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, uint16_t manuf, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId) {
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
SBuffer buf(32+len);
|
||||
buf.add8(Z_SREQ | Z_AF); // 24
|
||||
buf.add8(AF_DATA_REQUEST_EXT); // 02
|
||||
|
@ -342,6 +623,7 @@ void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterI
|
|||
}
|
||||
|
||||
ZigbeeZNPSend(buf.getBuffer(), buf.len());
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
@ -914,6 +1196,7 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind
|
|||
if (&to_group && dstLongAddr) { ResponseCmndChar_P(PSTR("Cannot have both \"ToDevice\" and \"ToGroup\"")); return; }
|
||||
if (!&to_group && !dstLongAddr) { ResponseCmndChar_P(PSTR("Missing \"ToDevice\" or \"ToGroup\"")); return; }
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
SBuffer buf(34);
|
||||
buf.add8(Z_SREQ | Z_ZDO);
|
||||
if (unbind) {
|
||||
|
@ -935,6 +1218,7 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind
|
|||
}
|
||||
|
||||
ZigbeeZNPSend(buf.getBuffer(), buf.len());
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
@ -961,6 +1245,7 @@ void CmndZbBindState(void) {
|
|||
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data);
|
||||
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
SBuffer buf(10);
|
||||
buf.add8(Z_SREQ | Z_ZDO); // 25
|
||||
buf.add8(ZDO_MGMT_BIND_REQ); // 33
|
||||
|
@ -968,6 +1253,7 @@ void CmndZbBindState(void) {
|
|||
buf.add8(0); // StartIndex = 0
|
||||
|
||||
ZigbeeZNPSend(buf.getBuffer(), buf.len());
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
@ -1191,6 +1477,7 @@ void CmndZbPermitJoin(void) {
|
|||
duration = 0xFF; // unlimited time
|
||||
}
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
SBuffer buf(34);
|
||||
buf.add8(Z_SREQ | Z_ZDO); // 25
|
||||
buf.add8(ZDO_MGMT_PERMIT_JOIN_REQ); // 36
|
||||
|
@ -1200,6 +1487,7 @@ void CmndZbPermitJoin(void) {
|
|||
buf.add8(0x00); // TCSignificance
|
||||
|
||||
ZigbeeZNPSend(buf.getBuffer(), buf.len());
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,585 @@
|
|||
/*
|
||||
xdrv_31_tasmota_client.ino - Support for external microcontroller on serial
|
||||
|
||||
Copyright (C) 2020 Andre Thomas and Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
/*********************************************************************************************\
|
||||
* Tasmota to microcontroller
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XDRV_31 31
|
||||
|
||||
#define CONST_STK_CRC_EOP 0x20
|
||||
|
||||
#define CMND_STK_GET_SYNC 0x30
|
||||
#define CMND_STK_SET_DEVICE 0x42
|
||||
#define CMND_STK_SET_DEVICE_EXT 0x45
|
||||
#define CMND_STK_ENTER_PROGMODE 0x50
|
||||
#define CMND_STK_LEAVE_PROGMODE 0x51
|
||||
#define CMND_STK_LOAD_ADDRESS 0x55
|
||||
#define CMND_STK_PROG_PAGE 0x64
|
||||
|
||||
/*************************************************\
|
||||
* Tasmota Client Specific Commands
|
||||
\*************************************************/
|
||||
|
||||
#define CMND_START 0xFC
|
||||
#define CMND_END 0xFD
|
||||
|
||||
#define CMND_FEATURES 0x01
|
||||
#define CMND_JSON 0x02
|
||||
#define CMND_FUNC_EVERY_SECOND 0x03
|
||||
#define CMND_FUNC_EVERY_100_MSECOND 0x04
|
||||
#define CMND_CLIENT_SEND 0x05
|
||||
#define CMND_PUBLISH_TELE 0x06
|
||||
#define CMND_EXECUTE_CMND 0x07
|
||||
|
||||
#define PARAM_DATA_START 0xFE
|
||||
#define PARAM_DATA_END 0xFF
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
|
||||
/*
|
||||
* Embedding class in here since its rather specific to Arduino bootloader
|
||||
*/
|
||||
|
||||
class SimpleHexParse {
|
||||
public:
|
||||
SimpleHexParse(void);
|
||||
uint8_t parseLine(char *hexline);
|
||||
uint8_t ptr_l = 0;
|
||||
uint8_t ptr_h = 0;
|
||||
bool PageIsReady = false;
|
||||
bool firstrun = true;
|
||||
bool EndOfFile = false;
|
||||
uint8_t FlashPage[128];
|
||||
uint8_t FlashPageIdx = 0;
|
||||
uint8_t layoverBuffer[16];
|
||||
uint8_t layoverIdx = 0;
|
||||
uint8_t getByte(char *hexline, uint8_t idx);
|
||||
};
|
||||
|
||||
SimpleHexParse::SimpleHexParse(void) {
|
||||
|
||||
}
|
||||
|
||||
uint8_t SimpleHexParse::parseLine(char *hexline) {
|
||||
if (layoverIdx) {
|
||||
memcpy(&FlashPage[0], &layoverBuffer[0], layoverIdx);
|
||||
FlashPageIdx = layoverIdx;
|
||||
layoverIdx = 0;
|
||||
}
|
||||
uint8_t len = getByte(hexline, 1);
|
||||
uint8_t addr_h = getByte(hexline, 2);
|
||||
uint8_t addr_l = getByte(hexline, 3);
|
||||
uint8_t rectype = getByte(hexline, 4);
|
||||
for (uint8_t idx = 0; idx < len; idx++) {
|
||||
if (FlashPageIdx < 128) {
|
||||
FlashPage[FlashPageIdx] = getByte(hexline, idx+5);
|
||||
FlashPageIdx++;
|
||||
} else { // We have layover bytes
|
||||
layoverBuffer[layoverIdx] = getByte(hexline, idx+5);
|
||||
layoverIdx++;
|
||||
}
|
||||
}
|
||||
if (1 == rectype) {
|
||||
EndOfFile = true;
|
||||
while (FlashPageIdx < 128) {
|
||||
FlashPage[FlashPageIdx] = 0xFF;
|
||||
FlashPageIdx++;
|
||||
}
|
||||
}
|
||||
if (FlashPageIdx == 128) {
|
||||
if (firstrun) {
|
||||
firstrun = false;
|
||||
} else {
|
||||
ptr_l += 0x40;
|
||||
if (ptr_l == 0) {
|
||||
ptr_l = 0;
|
||||
ptr_h++;
|
||||
}
|
||||
}
|
||||
firstrun = false;
|
||||
PageIsReady = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t SimpleHexParse::getByte(char* hexline, uint8_t idx) {
|
||||
char buff[3];
|
||||
buff[3] = '\0';
|
||||
memcpy(&buff, &hexline[(idx*2)-1], 2);
|
||||
return strtol(buff, 0, 16);
|
||||
}
|
||||
|
||||
/*
|
||||
* End of embedded class SimpleHexParse
|
||||
*/
|
||||
|
||||
struct TCLIENT {
|
||||
uint32_t spi_hex_size = 0;
|
||||
uint32_t spi_sector_counter = 0;
|
||||
uint8_t spi_sector_cursor = 0;
|
||||
uint8_t inverted = LOW;
|
||||
bool type = false;
|
||||
bool flashing = false;
|
||||
bool SerialEnabled = false;
|
||||
uint8_t waitstate = 0; // We use this so that features detection does not slow down other stuff on startup
|
||||
bool unsupported = false;
|
||||
} TClient;
|
||||
|
||||
typedef union {
|
||||
uint32_t data;
|
||||
struct {
|
||||
uint32_t func_json_append : 1; // Client supports providing a JSON for TELEPERIOD
|
||||
uint32_t func_every_second : 1; // Client supports receiving a FUNC_EVERY_SECOND callback with no response
|
||||
uint32_t func_every_100_msecond : 1; // Client supports receiving a FUNC_EVERY_100_MSECOND callback with no response
|
||||
uint32_t func_client_send : 1; // Client supports receiving commands with "client send xxx"
|
||||
uint32_t spare4 : 1;
|
||||
uint32_t spare5 : 1;
|
||||
uint32_t spare6 : 1;
|
||||
uint32_t spare7 : 1;
|
||||
uint32_t spare8 : 1;
|
||||
uint32_t spare9 : 1;
|
||||
uint32_t spare10 : 1;
|
||||
uint32_t spare11 : 1;
|
||||
uint32_t spare12 : 1;
|
||||
uint32_t spare13 : 1;
|
||||
uint32_t spare14 : 1;
|
||||
uint32_t spare15 : 1;
|
||||
uint32_t spare16 : 1;
|
||||
uint32_t spare17 : 1;
|
||||
uint32_t spare18 : 1;
|
||||
uint32_t spare19 : 1;
|
||||
uint32_t spare20 : 1;
|
||||
uint32_t spare21 : 1;
|
||||
uint32_t spare22 : 1;
|
||||
uint32_t spare23 : 1;
|
||||
uint32_t spare24 : 1;
|
||||
uint32_t spare25 : 1;
|
||||
uint32_t spare26 : 1;
|
||||
uint32_t spare27 : 1;
|
||||
uint32_t spare28 : 1;
|
||||
uint32_t spare29 : 1;
|
||||
uint32_t spare30 : 1;
|
||||
uint32_t spare31 : 1;
|
||||
};
|
||||
} TClientFeatureCfg;
|
||||
|
||||
/*
|
||||
* The structure below must remain 4 byte aligned to be compatible with
|
||||
* Tasmota as master
|
||||
*/
|
||||
|
||||
struct TCLIENT_FEATURES {
|
||||
uint32_t features_version;
|
||||
TClientFeatureCfg features;
|
||||
} TClientSettings;
|
||||
|
||||
struct TCLIENT_COMMAND {
|
||||
uint8_t command;
|
||||
uint8_t parameter;
|
||||
uint8_t unused2;
|
||||
uint8_t unused3;
|
||||
} TClientCommand;
|
||||
|
||||
TasmotaSerial *TasmotaClient_Serial;
|
||||
|
||||
uint32_t TasmotaClient_FlashStart(void) {
|
||||
return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side
|
||||
}
|
||||
|
||||
uint8_t TasmotaClient_UpdateInit(void) {
|
||||
TClient.spi_hex_size = 0;
|
||||
TClient.spi_sector_counter = TasmotaClient_FlashStart(); // Reset the pre-defined write address where firmware will temporarily be stored
|
||||
TClient.spi_sector_cursor = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TasmotaClient_Reset(void) {
|
||||
if (TClient.SerialEnabled) {
|
||||
digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), !TClient.inverted);
|
||||
delay(1);
|
||||
digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), TClient.inverted);
|
||||
delay(1);
|
||||
digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), !TClient.inverted);
|
||||
delay(5);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t TasmotaClient_waitForSerialData(int dataCount, int timeout) {
|
||||
int timer = 0;
|
||||
while (timer < timeout) {
|
||||
if (TasmotaClient_Serial->available() >= dataCount) {
|
||||
return 1;
|
||||
}
|
||||
delay(1);
|
||||
timer++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t TasmotaClient_sendBytes(uint8_t* bytes, int count) {
|
||||
TasmotaClient_Serial->write(bytes, count);
|
||||
TasmotaClient_waitForSerialData(2, 250);
|
||||
uint8_t sync = TasmotaClient_Serial->read();
|
||||
uint8_t ok = TasmotaClient_Serial->read();
|
||||
if ((sync == 0x14) && (ok == 0x10)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t TasmotaClient_execCmd(uint8_t cmd) {
|
||||
uint8_t bytes[] = { cmd, CONST_STK_CRC_EOP };
|
||||
return TasmotaClient_sendBytes(bytes, 2);
|
||||
}
|
||||
|
||||
uint8_t TasmotaClient_execParam(uint8_t cmd, uint8_t* params, int count) {
|
||||
uint8_t bytes[32];
|
||||
bytes[0] = cmd;
|
||||
int i = 0;
|
||||
while (i < count) {
|
||||
bytes[i + 1] = params[i];
|
||||
i++;
|
||||
}
|
||||
bytes[i + 1] = CONST_STK_CRC_EOP;
|
||||
return TasmotaClient_sendBytes(bytes, i + 2);
|
||||
}
|
||||
|
||||
uint8_t TasmotaClient_exitProgMode(void) {
|
||||
return TasmotaClient_execCmd(CMND_STK_LEAVE_PROGMODE); // Exit programming mode
|
||||
}
|
||||
|
||||
uint8_t TasmotaClient_SetupFlash(void) {
|
||||
uint8_t ProgParams[] = {0x86, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00};
|
||||
uint8_t ExtProgParams[] = {0x05, 0x04, 0xd7, 0xc2, 0x00};
|
||||
TasmotaClient_Serial->begin(USE_TASMOTA_CLIENT_FLASH_SPEED);
|
||||
if (TasmotaClient_Serial->hardwareSerial()) {
|
||||
ClaimSerial();
|
||||
}
|
||||
|
||||
TasmotaClient_Reset();
|
||||
|
||||
uint8_t timeout = 0;
|
||||
uint8_t no_error = 0;
|
||||
while (50 > timeout) {
|
||||
if (TasmotaClient_execCmd(CMND_STK_GET_SYNC)) {
|
||||
timeout = 200;
|
||||
no_error = 1;
|
||||
}
|
||||
timeout++;
|
||||
delay(1);
|
||||
}
|
||||
if (no_error) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Found bootloader"));
|
||||
} else {
|
||||
no_error = 0;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Bootloader could not be found"));
|
||||
}
|
||||
if (no_error) {
|
||||
if (TasmotaClient_execParam(CMND_STK_SET_DEVICE, ProgParams, sizeof(ProgParams))) {
|
||||
} else {
|
||||
no_error = 0;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Could not configure device for programming (1)"));
|
||||
}
|
||||
}
|
||||
if (no_error) {
|
||||
if (TasmotaClient_execParam(CMND_STK_SET_DEVICE_EXT, ExtProgParams, sizeof(ExtProgParams))) {
|
||||
} else {
|
||||
no_error = 0;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Could not configure device for programming (2)"));
|
||||
}
|
||||
}
|
||||
if (no_error) {
|
||||
if (TasmotaClient_execCmd(CMND_STK_ENTER_PROGMODE)) {
|
||||
} else {
|
||||
no_error = 0;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Failed to put bootloader into programming mode"));
|
||||
}
|
||||
}
|
||||
return no_error;
|
||||
}
|
||||
|
||||
uint8_t TasmotaClient_loadAddress(uint8_t adrHi, uint8_t adrLo) {
|
||||
uint8_t params[] = { adrLo, adrHi };
|
||||
return TasmotaClient_execParam(CMND_STK_LOAD_ADDRESS, params, sizeof(params));
|
||||
}
|
||||
|
||||
void TasmotaClient_FlashPage(uint8_t addr_h, uint8_t addr_l, uint8_t* data) {
|
||||
uint8_t Header[] = {CMND_STK_PROG_PAGE, 0x00, 0x80, 0x46};
|
||||
TasmotaClient_loadAddress(addr_h, addr_l);
|
||||
TasmotaClient_Serial->write(Header, 4);
|
||||
for (int i = 0; i < 128; i++) {
|
||||
TasmotaClient_Serial->write(data[i]);
|
||||
}
|
||||
TasmotaClient_Serial->write(CONST_STK_CRC_EOP);
|
||||
TasmotaClient_waitForSerialData(2, 250);
|
||||
TasmotaClient_Serial->read();
|
||||
TasmotaClient_Serial->read();
|
||||
}
|
||||
|
||||
void TasmotaClient_Flash(void) {
|
||||
bool reading = true;
|
||||
uint32_t read = 0;
|
||||
uint32_t processed = 0;
|
||||
char thishexline[50];
|
||||
uint8_t position = 0;
|
||||
char* flash_buffer;
|
||||
|
||||
SimpleHexParse hexParse = SimpleHexParse();
|
||||
|
||||
if (!TasmotaClient_SetupFlash()) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Flashing aborted!"));
|
||||
TClient.flashing = false;
|
||||
restart_flag = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
flash_buffer = new char[SPI_FLASH_SEC_SIZE];
|
||||
uint32_t flash_start = TasmotaClient_FlashStart() * SPI_FLASH_SEC_SIZE;
|
||||
while (reading) {
|
||||
ESP.flashRead(flash_start + read, (uint32_t*)flash_buffer, SPI_FLASH_SEC_SIZE);
|
||||
read = read + SPI_FLASH_SEC_SIZE;
|
||||
if (read >= TClient.spi_hex_size) {
|
||||
reading = false;
|
||||
}
|
||||
for (uint32_t ca = 0; ca < SPI_FLASH_SEC_SIZE; ca++) {
|
||||
processed++;
|
||||
if ((processed <= TClient.spi_hex_size) && (!hexParse.EndOfFile)) {
|
||||
if (':' == flash_buffer[ca]) {
|
||||
position = 0;
|
||||
}
|
||||
if (0x0D == flash_buffer[ca]) {
|
||||
thishexline[position] = 0;
|
||||
hexParse.parseLine(thishexline);
|
||||
if (hexParse.PageIsReady) {
|
||||
TasmotaClient_FlashPage(hexParse.ptr_h, hexParse.ptr_l, hexParse.FlashPage);
|
||||
hexParse.PageIsReady = false;
|
||||
hexParse.FlashPageIdx = 0;
|
||||
}
|
||||
} else {
|
||||
if (0x0A != flash_buffer[ca]) {
|
||||
thishexline[position] = flash_buffer[ca];
|
||||
position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TasmotaClient_exitProgMode();
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Flash done!"));
|
||||
TClient.flashing = false;
|
||||
restart_flag = 2;
|
||||
}
|
||||
|
||||
void TasmotaClient_SetFlagFlashing(bool value) {
|
||||
TClient.flashing = value;
|
||||
}
|
||||
|
||||
bool TasmotaClient_GetFlagFlashing(void) {
|
||||
return TClient.flashing;
|
||||
}
|
||||
|
||||
void TasmotaClient_WriteBuffer(uint8_t *buf, size_t size) {
|
||||
if (0 == TClient.spi_sector_cursor) { // Starting a new sector write so we need to erase it first
|
||||
ESP.flashEraseSector(TClient.spi_sector_counter);
|
||||
}
|
||||
TClient.spi_sector_cursor++;
|
||||
ESP.flashWrite((TClient.spi_sector_counter * SPI_FLASH_SEC_SIZE) + ((TClient.spi_sector_cursor-1)*2048), (uint32_t*)buf, size);
|
||||
TClient.spi_hex_size = TClient.spi_hex_size + size;
|
||||
if (2 == TClient.spi_sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase
|
||||
TClient.spi_sector_cursor = 0;
|
||||
TClient.spi_sector_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
void TasmotaClient_Init(void) {
|
||||
if (TClient.type) {
|
||||
return;
|
||||
}
|
||||
if (10 > TClient.waitstate) {
|
||||
TClient.waitstate++;
|
||||
return;
|
||||
}
|
||||
if (!TClient.SerialEnabled) {
|
||||
if (PinUsed(GPIO_TASMOTACLIENT_RXD) && PinUsed(GPIO_TASMOTACLIENT_TXD) &&
|
||||
(PinUsed(GPIO_TASMOTACLIENT_RST) || PinUsed(GPIO_TASMOTACLIENT_RST_INV))) {
|
||||
TasmotaClient_Serial = new TasmotaSerial(Pin(GPIO_TASMOTACLIENT_RXD), Pin(GPIO_TASMOTACLIENT_TXD), 1, 0, 200);
|
||||
if (TasmotaClient_Serial->begin(USE_TASMOTA_CLIENT_SERIAL_SPEED)) {
|
||||
if (TasmotaClient_Serial->hardwareSerial()) {
|
||||
ClaimSerial();
|
||||
}
|
||||
TasmotaClient_Serial->setTimeout(100); // Theo 20200502 - increase from 50
|
||||
if (PinUsed(GPIO_TASMOTACLIENT_RST_INV)) {
|
||||
SetPin(Pin(GPIO_TASMOTACLIENT_RST_INV), GPIO_TASMOTACLIENT_RST);
|
||||
TClient.inverted = HIGH;
|
||||
}
|
||||
pinMode(Pin(GPIO_TASMOTACLIENT_RST), OUTPUT);
|
||||
TClient.SerialEnabled = true;
|
||||
TasmotaClient_Reset();
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Enabled"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (TClient.SerialEnabled) { // All go for hardware now we need to detect features if there are any
|
||||
TasmotaClient_sendCmnd(CMND_FEATURES, 0);
|
||||
char buffer[32] = { 0 };
|
||||
TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer));
|
||||
uint8_t len = TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer));
|
||||
|
||||
if (len) { AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t*)buffer, len); } // Theo 20200502 - DMP: 99 17 34 01 02 00 00 00
|
||||
|
||||
memcpy(&TClientSettings, &buffer, sizeof(TClientSettings));
|
||||
if (20191129 == TClientSettings.features_version) {
|
||||
TClient.type = true;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Version %u"), TClientSettings.features_version);
|
||||
} else {
|
||||
if ((!TClient.unsupported) && (TClientSettings.features_version > 0)) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Version %u not supported!"), TClientSettings.features_version);
|
||||
TClient.unsupported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TasmotaClient_Show(void) {
|
||||
if ((TClient.type) && (TClientSettings.features.func_json_append)) {
|
||||
char buffer[100];
|
||||
TasmotaClient_sendCmnd(CMND_JSON, 0);
|
||||
TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)-1);
|
||||
uint8_t len = TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)-1);
|
||||
buffer[len] = '\0';
|
||||
ResponseAppend_P(PSTR(",\"TasmotaClient\":%s"), buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void TasmotaClient_sendCmnd(uint8_t cmnd, uint8_t param) {
|
||||
TClientCommand.command = cmnd;
|
||||
TClientCommand.parameter = param;
|
||||
char buffer[sizeof(TClientCommand)+2];
|
||||
buffer[0] = CMND_START;
|
||||
memcpy(&buffer[1], &TClientCommand, sizeof(TClientCommand));
|
||||
buffer[sizeof(TClientCommand)+1] = CMND_END;
|
||||
|
||||
TasmotaClient_Serial->flush(); // Theo 20200502
|
||||
|
||||
for (uint8_t ca = 0; ca < sizeof(buffer); ca++) {
|
||||
TasmotaClient_Serial->write(buffer[ca]);
|
||||
}
|
||||
}
|
||||
|
||||
#define D_PRFX_CLIENT "Client"
|
||||
#define D_CMND_CLIENT_RESET "Reset"
|
||||
#define D_CMND_CLIENT_SEND "Send"
|
||||
|
||||
const char kTasmotaClientCommands[] PROGMEM = D_PRFX_CLIENT "|"
|
||||
D_CMND_CLIENT_RESET "|" D_CMND_CLIENT_SEND;
|
||||
|
||||
void (* const TasmotaClientCommand[])(void) PROGMEM = {
|
||||
&CmndClientReset, &CmndClientSend };
|
||||
|
||||
void CmndClientReset(void) {
|
||||
TasmotaClient_Reset();
|
||||
TClient.type = false; // Force redetection
|
||||
TClient.waitstate = 7; // give it at least 3 seconds to restart from bootloader
|
||||
TClient.unsupported = false; // Reset unsupported flag
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
void CmndClientSend(void) {
|
||||
if (0 < XdrvMailbox.data_len) {
|
||||
TasmotaClient_sendCmnd(CMND_CLIENT_SEND, XdrvMailbox.data_len);
|
||||
TasmotaClient_Serial->write(char(PARAM_DATA_START));
|
||||
for (uint8_t idx = 0; idx < XdrvMailbox.data_len; idx++) {
|
||||
TasmotaClient_Serial->write(XdrvMailbox.data[idx]);
|
||||
}
|
||||
TasmotaClient_Serial->write(char(PARAM_DATA_END));
|
||||
}
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
void TasmotaClient_ProcessIn(void) {
|
||||
uint8_t cmnd = TasmotaClient_Serial->read();
|
||||
if (CMND_START == cmnd) {
|
||||
TasmotaClient_waitForSerialData(sizeof(TClientCommand),50);
|
||||
uint8_t buffer[sizeof(TClientCommand)];
|
||||
for (uint8_t idx = 0; idx < sizeof(TClientCommand); idx++) {
|
||||
buffer[idx] = TasmotaClient_Serial->read();
|
||||
}
|
||||
TasmotaClient_Serial->read(); // read trailing byte of command
|
||||
memcpy(&TClientCommand, &buffer, sizeof(TClientCommand));
|
||||
char inbuf[TClientCommand.parameter+1];
|
||||
TasmotaClient_waitForSerialData(TClientCommand.parameter, 50);
|
||||
TasmotaClient_Serial->read(); // Read leading byte
|
||||
for (uint8_t idx = 0; idx < TClientCommand.parameter; idx++) {
|
||||
inbuf[idx] = TasmotaClient_Serial->read();
|
||||
}
|
||||
TasmotaClient_Serial->read(); // Read trailing byte
|
||||
inbuf[TClientCommand.parameter] = '\0';
|
||||
|
||||
if (CMND_PUBLISH_TELE == TClientCommand.command) { // We need to publish stat/ with incoming stream as content
|
||||
Response_P(PSTR("{\"TasmotaClient\":"));
|
||||
ResponseAppend_P("%s", inbuf);
|
||||
ResponseJsonEnd();
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data);
|
||||
XdrvRulesProcess();
|
||||
}
|
||||
if (CMND_EXECUTE_CMND == TClientCommand.command) { // We need to execute the incoming command
|
||||
ExecuteCommand(inbuf, SRC_IGNORE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xdrv31(uint8_t function) {
|
||||
bool result = false;
|
||||
|
||||
switch (function) {
|
||||
case FUNC_EVERY_100_MSECOND:
|
||||
if (TClient.type) {
|
||||
if (TasmotaClient_Serial->available()) {
|
||||
TasmotaClient_ProcessIn();
|
||||
}
|
||||
if (TClientSettings.features.func_every_100_msecond) {
|
||||
TasmotaClient_sendCmnd(CMND_FUNC_EVERY_100_MSECOND, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
if ((TClient.type) && (TClientSettings.features.func_every_second)) {
|
||||
TasmotaClient_sendCmnd(CMND_FUNC_EVERY_SECOND, 0);
|
||||
}
|
||||
TasmotaClient_Init();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
if ((TClient.type) && (TClientSettings.features.func_json_append)) {
|
||||
TasmotaClient_Show();
|
||||
}
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
result = DecodeCommand(kTasmotaClientCommands, TasmotaClientCommand);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_TASMOTA_CLIENT
|
|
@ -1,615 +0,0 @@
|
|||
/*
|
||||
xdrv_31_tasmota_slave.ino - Support for external microcontroller slave on serial
|
||||
|
||||
Copyright (C) 2020 Andre Thomas and Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_TASMOTA_SLAVE
|
||||
/*********************************************************************************************\
|
||||
* Tasmota slave
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XDRV_31 31
|
||||
|
||||
#define CONST_STK_CRC_EOP 0x20
|
||||
|
||||
#define CMND_STK_GET_SYNC 0x30
|
||||
#define CMND_STK_SET_DEVICE 0x42
|
||||
#define CMND_STK_SET_DEVICE_EXT 0x45
|
||||
#define CMND_STK_ENTER_PROGMODE 0x50
|
||||
#define CMND_STK_LEAVE_PROGMODE 0x51
|
||||
#define CMND_STK_LOAD_ADDRESS 0x55
|
||||
#define CMND_STK_PROG_PAGE 0x64
|
||||
|
||||
/*************************************************\
|
||||
* Tasmota Slave Specific Commands
|
||||
\*************************************************/
|
||||
|
||||
#define CMND_START 0xFC
|
||||
#define CMND_END 0xFD
|
||||
|
||||
#define CMND_FEATURES 0x01
|
||||
#define CMND_JSON 0x02
|
||||
#define CMND_FUNC_EVERY_SECOND 0x03
|
||||
#define CMND_FUNC_EVERY_100_MSECOND 0x04
|
||||
#define CMND_SLAVE_SEND 0x05
|
||||
#define CMND_PUBLISH_TELE 0x06
|
||||
#define CMND_EXECUTE_CMND 0x07
|
||||
|
||||
#define PARAM_DATA_START 0xFE
|
||||
#define PARAM_DATA_END 0xFF
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
|
||||
/*
|
||||
* Embedding class in here since its rather specific to Arduino bootloader
|
||||
*/
|
||||
|
||||
class SimpleHexParse {
|
||||
public:
|
||||
SimpleHexParse(void);
|
||||
uint8_t parseLine(char *hexline);
|
||||
uint8_t ptr_l = 0;
|
||||
uint8_t ptr_h = 0;
|
||||
bool PageIsReady = false;
|
||||
bool firstrun = true;
|
||||
bool EndOfFile = false;
|
||||
uint8_t FlashPage[128];
|
||||
uint8_t FlashPageIdx = 0;
|
||||
uint8_t layoverBuffer[16];
|
||||
uint8_t layoverIdx = 0;
|
||||
uint8_t getByte(char *hexline, uint8_t idx);
|
||||
};
|
||||
|
||||
SimpleHexParse::SimpleHexParse(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint8_t SimpleHexParse::parseLine(char *hexline)
|
||||
{
|
||||
if (layoverIdx) {
|
||||
memcpy(&FlashPage[0], &layoverBuffer[0], layoverIdx);
|
||||
FlashPageIdx = layoverIdx;
|
||||
layoverIdx = 0;
|
||||
}
|
||||
uint8_t len = getByte(hexline, 1);
|
||||
uint8_t addr_h = getByte(hexline, 2);
|
||||
uint8_t addr_l = getByte(hexline, 3);
|
||||
uint8_t rectype = getByte(hexline, 4);
|
||||
for (uint8_t idx = 0; idx < len; idx++) {
|
||||
if (FlashPageIdx < 128) {
|
||||
FlashPage[FlashPageIdx] = getByte(hexline, idx+5);
|
||||
FlashPageIdx++;
|
||||
} else { // We have layover bytes
|
||||
layoverBuffer[layoverIdx] = getByte(hexline, idx+5);
|
||||
layoverIdx++;
|
||||
}
|
||||
}
|
||||
if (1 == rectype) {
|
||||
EndOfFile = true;
|
||||
while (FlashPageIdx < 128) {
|
||||
FlashPage[FlashPageIdx] = 0xFF;
|
||||
FlashPageIdx++;
|
||||
}
|
||||
}
|
||||
if (FlashPageIdx == 128) {
|
||||
if (firstrun) {
|
||||
firstrun = false;
|
||||
} else {
|
||||
ptr_l += 0x40;
|
||||
if (ptr_l == 0) {
|
||||
ptr_l = 0;
|
||||
ptr_h++;
|
||||
}
|
||||
}
|
||||
firstrun = false;
|
||||
PageIsReady = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t SimpleHexParse::getByte(char* hexline, uint8_t idx)
|
||||
{
|
||||
char buff[3];
|
||||
buff[3] = '\0';
|
||||
memcpy(&buff, &hexline[(idx*2)-1], 2);
|
||||
return strtol(buff, 0, 16);
|
||||
}
|
||||
|
||||
/*
|
||||
* End of embedded class SimpleHexParse
|
||||
*/
|
||||
|
||||
struct TSLAVE {
|
||||
uint32_t spi_hex_size = 0;
|
||||
uint32_t spi_sector_counter = 0;
|
||||
uint8_t spi_sector_cursor = 0;
|
||||
uint8_t inverted = LOW;
|
||||
bool type = false;
|
||||
bool flashing = false;
|
||||
bool SerialEnabled = false;
|
||||
uint8_t waitstate = 0; // We use this so that features detection does not slow down other stuff on startup
|
||||
bool unsupported = false;
|
||||
} TSlave;
|
||||
|
||||
typedef union {
|
||||
uint32_t data;
|
||||
struct {
|
||||
uint32_t func_json_append : 1; // Slave supports providing a JSON for TELEPERIOD
|
||||
uint32_t func_every_second : 1; // Slave supports receiving a FUNC_EVERY_SECOND callback with no response
|
||||
uint32_t func_every_100_msecond : 1; // Slave supports receiving a FUNC_EVERY_100_MSECOND callback with no response
|
||||
uint32_t func_slave_send : 1; // Slave supports receiving commands with "slave send xxx"
|
||||
uint32_t spare4 : 1;
|
||||
uint32_t spare5 : 1;
|
||||
uint32_t spare6 : 1;
|
||||
uint32_t spare7 : 1;
|
||||
uint32_t spare8 : 1;
|
||||
uint32_t spare9 : 1;
|
||||
uint32_t spare10 : 1;
|
||||
uint32_t spare11 : 1;
|
||||
uint32_t spare12 : 1;
|
||||
uint32_t spare13 : 1;
|
||||
uint32_t spare14 : 1;
|
||||
uint32_t spare15 : 1;
|
||||
uint32_t spare16 : 1;
|
||||
uint32_t spare17 : 1;
|
||||
uint32_t spare18 : 1;
|
||||
uint32_t spare19 : 1;
|
||||
uint32_t spare20 : 1;
|
||||
uint32_t spare21 : 1;
|
||||
uint32_t spare22 : 1;
|
||||
uint32_t spare23 : 1;
|
||||
uint32_t spare24 : 1;
|
||||
uint32_t spare25 : 1;
|
||||
uint32_t spare26 : 1;
|
||||
uint32_t spare27 : 1;
|
||||
uint32_t spare28 : 1;
|
||||
uint32_t spare29 : 1;
|
||||
uint32_t spare30 : 1;
|
||||
uint32_t spare31 : 1;
|
||||
};
|
||||
} TSlaveFeatureCfg;
|
||||
|
||||
/*
|
||||
* The structure below must remain 4 byte aligned to be compatible with
|
||||
* Tasmota as master
|
||||
*/
|
||||
|
||||
struct TSLAVE_FEATURES {
|
||||
uint32_t features_version;
|
||||
TSlaveFeatureCfg features;
|
||||
} TSlaveSettings;
|
||||
|
||||
struct TSLAVE_COMMAND {
|
||||
uint8_t command;
|
||||
uint8_t parameter;
|
||||
uint8_t unused2;
|
||||
uint8_t unused3;
|
||||
} TSlaveCommand;
|
||||
|
||||
TasmotaSerial *TasmotaSlave_Serial;
|
||||
|
||||
uint32_t TasmotaSlave_FlashStart(void)
|
||||
{
|
||||
return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side
|
||||
}
|
||||
|
||||
uint8_t TasmotaSlave_UpdateInit(void)
|
||||
{
|
||||
TSlave.spi_hex_size = 0;
|
||||
TSlave.spi_sector_counter = TasmotaSlave_FlashStart(); // Reset the pre-defined write address where firmware will temporarily be stored
|
||||
TSlave.spi_sector_cursor = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TasmotaSlave_Reset(void)
|
||||
{
|
||||
if (TSlave.SerialEnabled) {
|
||||
digitalWrite(Pin(GPIO_TASMOTASLAVE_RST), !TSlave.inverted);
|
||||
delay(1);
|
||||
digitalWrite(Pin(GPIO_TASMOTASLAVE_RST), TSlave.inverted);
|
||||
delay(1);
|
||||
digitalWrite(Pin(GPIO_TASMOTASLAVE_RST), !TSlave.inverted);
|
||||
delay(5);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t TasmotaSlave_waitForSerialData(int dataCount, int timeout)
|
||||
{
|
||||
int timer = 0;
|
||||
while (timer < timeout) {
|
||||
if (TasmotaSlave_Serial->available() >= dataCount) {
|
||||
return 1;
|
||||
}
|
||||
delay(1);
|
||||
timer++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t TasmotaSlave_sendBytes(uint8_t* bytes, int count)
|
||||
{
|
||||
TasmotaSlave_Serial->write(bytes, count);
|
||||
TasmotaSlave_waitForSerialData(2, 250);
|
||||
uint8_t sync = TasmotaSlave_Serial->read();
|
||||
uint8_t ok = TasmotaSlave_Serial->read();
|
||||
if ((sync == 0x14) && (ok == 0x10)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t TasmotaSlave_execCmd(uint8_t cmd)
|
||||
{
|
||||
uint8_t bytes[] = { cmd, CONST_STK_CRC_EOP };
|
||||
return TasmotaSlave_sendBytes(bytes, 2);
|
||||
}
|
||||
|
||||
uint8_t TasmotaSlave_execParam(uint8_t cmd, uint8_t* params, int count)
|
||||
{
|
||||
uint8_t bytes[32];
|
||||
bytes[0] = cmd;
|
||||
int i = 0;
|
||||
while (i < count) {
|
||||
bytes[i + 1] = params[i];
|
||||
i++;
|
||||
}
|
||||
bytes[i + 1] = CONST_STK_CRC_EOP;
|
||||
return TasmotaSlave_sendBytes(bytes, i + 2);
|
||||
}
|
||||
|
||||
uint8_t TasmotaSlave_exitProgMode(void)
|
||||
{
|
||||
return TasmotaSlave_execCmd(CMND_STK_LEAVE_PROGMODE); // Exit programming mode
|
||||
}
|
||||
|
||||
uint8_t TasmotaSlave_SetupFlash(void)
|
||||
{
|
||||
uint8_t ProgParams[] = {0x86, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00};
|
||||
uint8_t ExtProgParams[] = {0x05, 0x04, 0xd7, 0xc2, 0x00};
|
||||
TasmotaSlave_Serial->begin(USE_TASMOTA_SLAVE_FLASH_SPEED);
|
||||
if (TasmotaSlave_Serial->hardwareSerial()) {
|
||||
ClaimSerial();
|
||||
}
|
||||
|
||||
TasmotaSlave_Reset();
|
||||
|
||||
uint8_t timeout = 0;
|
||||
uint8_t no_error = 0;
|
||||
while (50 > timeout) {
|
||||
if (TasmotaSlave_execCmd(CMND_STK_GET_SYNC)) {
|
||||
timeout = 200;
|
||||
no_error = 1;
|
||||
}
|
||||
timeout++;
|
||||
delay(1);
|
||||
}
|
||||
if (no_error) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Found bootloader"));
|
||||
} else {
|
||||
no_error = 0;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Bootloader could not be found"));
|
||||
}
|
||||
if (no_error) {
|
||||
if (TasmotaSlave_execParam(CMND_STK_SET_DEVICE, ProgParams, sizeof(ProgParams))) {
|
||||
} else {
|
||||
no_error = 0;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Could not configure device for programming (1)"));
|
||||
}
|
||||
}
|
||||
if (no_error) {
|
||||
if (TasmotaSlave_execParam(CMND_STK_SET_DEVICE_EXT, ExtProgParams, sizeof(ExtProgParams))) {
|
||||
} else {
|
||||
no_error = 0;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Could not configure device for programming (2)"));
|
||||
}
|
||||
}
|
||||
if (no_error) {
|
||||
if (TasmotaSlave_execCmd(CMND_STK_ENTER_PROGMODE)) {
|
||||
} else {
|
||||
no_error = 0;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Failed to put bootloader into programming mode"));
|
||||
}
|
||||
}
|
||||
return no_error;
|
||||
}
|
||||
|
||||
uint8_t TasmotaSlave_loadAddress(uint8_t adrHi, uint8_t adrLo)
|
||||
{
|
||||
uint8_t params[] = { adrLo, adrHi };
|
||||
return TasmotaSlave_execParam(CMND_STK_LOAD_ADDRESS, params, sizeof(params));
|
||||
}
|
||||
|
||||
void TasmotaSlave_FlashPage(uint8_t addr_h, uint8_t addr_l, uint8_t* data)
|
||||
{
|
||||
uint8_t Header[] = {CMND_STK_PROG_PAGE, 0x00, 0x80, 0x46};
|
||||
TasmotaSlave_loadAddress(addr_h, addr_l);
|
||||
TasmotaSlave_Serial->write(Header, 4);
|
||||
for (int i = 0; i < 128; i++) {
|
||||
TasmotaSlave_Serial->write(data[i]);
|
||||
}
|
||||
TasmotaSlave_Serial->write(CONST_STK_CRC_EOP);
|
||||
TasmotaSlave_waitForSerialData(2, 250);
|
||||
TasmotaSlave_Serial->read();
|
||||
TasmotaSlave_Serial->read();
|
||||
}
|
||||
|
||||
void TasmotaSlave_Flash(void)
|
||||
{
|
||||
bool reading = true;
|
||||
uint32_t read = 0;
|
||||
uint32_t processed = 0;
|
||||
char thishexline[50];
|
||||
uint8_t position = 0;
|
||||
char* flash_buffer;
|
||||
|
||||
SimpleHexParse hexParse = SimpleHexParse();
|
||||
|
||||
if (!TasmotaSlave_SetupFlash()) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Flashing aborted!"));
|
||||
TSlave.flashing = false;
|
||||
restart_flag = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
flash_buffer = new char[SPI_FLASH_SEC_SIZE];
|
||||
uint32_t flash_start = TasmotaSlave_FlashStart() * SPI_FLASH_SEC_SIZE;
|
||||
while (reading) {
|
||||
ESP.flashRead(flash_start + read, (uint32_t*)flash_buffer, SPI_FLASH_SEC_SIZE);
|
||||
read = read + SPI_FLASH_SEC_SIZE;
|
||||
if (read >= TSlave.spi_hex_size) {
|
||||
reading = false;
|
||||
}
|
||||
for (uint32_t ca = 0; ca < SPI_FLASH_SEC_SIZE; ca++) {
|
||||
processed++;
|
||||
if ((processed <= TSlave.spi_hex_size) && (!hexParse.EndOfFile)) {
|
||||
if (':' == flash_buffer[ca]) {
|
||||
position = 0;
|
||||
}
|
||||
if (0x0D == flash_buffer[ca]) {
|
||||
thishexline[position] = 0;
|
||||
hexParse.parseLine(thishexline);
|
||||
if (hexParse.PageIsReady) {
|
||||
TasmotaSlave_FlashPage(hexParse.ptr_h, hexParse.ptr_l, hexParse.FlashPage);
|
||||
hexParse.PageIsReady = false;
|
||||
hexParse.FlashPageIdx = 0;
|
||||
}
|
||||
} else {
|
||||
if (0x0A != flash_buffer[ca]) {
|
||||
thishexline[position] = flash_buffer[ca];
|
||||
position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TasmotaSlave_exitProgMode();
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Flash done!"));
|
||||
TSlave.flashing = false;
|
||||
restart_flag = 2;
|
||||
}
|
||||
|
||||
void TasmotaSlave_SetFlagFlashing(bool value)
|
||||
{
|
||||
TSlave.flashing = value;
|
||||
}
|
||||
|
||||
bool TasmotaSlave_GetFlagFlashing(void)
|
||||
{
|
||||
return TSlave.flashing;
|
||||
}
|
||||
|
||||
void TasmotaSlave_WriteBuffer(uint8_t *buf, size_t size)
|
||||
{
|
||||
if (0 == TSlave.spi_sector_cursor) { // Starting a new sector write so we need to erase it first
|
||||
ESP.flashEraseSector(TSlave.spi_sector_counter);
|
||||
}
|
||||
TSlave.spi_sector_cursor++;
|
||||
ESP.flashWrite((TSlave.spi_sector_counter * SPI_FLASH_SEC_SIZE) + ((TSlave.spi_sector_cursor-1)*2048), (uint32_t*)buf, size);
|
||||
TSlave.spi_hex_size = TSlave.spi_hex_size + size;
|
||||
if (2 == TSlave.spi_sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase
|
||||
TSlave.spi_sector_cursor = 0;
|
||||
TSlave.spi_sector_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
void TasmotaSlave_Init(void)
|
||||
{
|
||||
if (TSlave.type) {
|
||||
return;
|
||||
}
|
||||
if (10 > TSlave.waitstate) {
|
||||
TSlave.waitstate++;
|
||||
return;
|
||||
}
|
||||
if (!TSlave.SerialEnabled) {
|
||||
if (PinUsed(GPIO_TASMOTASLAVE_RXD) && PinUsed(GPIO_TASMOTASLAVE_TXD) &&
|
||||
(PinUsed(GPIO_TASMOTASLAVE_RST) || PinUsed(GPIO_TASMOTASLAVE_RST_INV))) {
|
||||
TasmotaSlave_Serial = new TasmotaSerial(Pin(GPIO_TASMOTASLAVE_RXD), Pin(GPIO_TASMOTASLAVE_TXD), 1, 0, 200);
|
||||
if (TasmotaSlave_Serial->begin(USE_TASMOTA_SLAVE_SERIAL_SPEED)) {
|
||||
if (TasmotaSlave_Serial->hardwareSerial()) {
|
||||
ClaimSerial();
|
||||
}
|
||||
TasmotaSlave_Serial->setTimeout(100); // Theo 20200502 - increase from 50
|
||||
if (PinUsed(GPIO_TASMOTASLAVE_RST_INV)) {
|
||||
SetPin(Pin(GPIO_TASMOTASLAVE_RST_INV), GPIO_TASMOTASLAVE_RST);
|
||||
TSlave.inverted = HIGH;
|
||||
}
|
||||
pinMode(Pin(GPIO_TASMOTASLAVE_RST), OUTPUT);
|
||||
TSlave.SerialEnabled = true;
|
||||
TasmotaSlave_Reset();
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Enabled"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (TSlave.SerialEnabled) { // All go for hardware now we need to detect features if there are any
|
||||
TasmotaSlave_sendCmnd(CMND_FEATURES, 0);
|
||||
char buffer[32] = { 0 };
|
||||
TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer));
|
||||
uint8_t len = TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer));
|
||||
|
||||
if (len) { AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t*)buffer, len); } // Theo 20200502 - DMP: 99 17 34 01 02 00 00 00
|
||||
|
||||
memcpy(&TSlaveSettings, &buffer, sizeof(TSlaveSettings));
|
||||
if (20191129 == TSlaveSettings.features_version) {
|
||||
TSlave.type = true;
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Version %u"), TSlaveSettings.features_version);
|
||||
} else {
|
||||
if ((!TSlave.unsupported) && (TSlaveSettings.features_version > 0)) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Version %u not supported!"), TSlaveSettings.features_version);
|
||||
TSlave.unsupported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TasmotaSlave_Show(void)
|
||||
{
|
||||
if ((TSlave.type) && (TSlaveSettings.features.func_json_append)) {
|
||||
char buffer[100];
|
||||
TasmotaSlave_sendCmnd(CMND_JSON, 0);
|
||||
TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)-1);
|
||||
uint8_t len = TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)-1);
|
||||
buffer[len] = '\0';
|
||||
ResponseAppend_P(PSTR(",\"TasmotaSlave\":%s"), buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void TasmotaSlave_sendCmnd(uint8_t cmnd, uint8_t param)
|
||||
{
|
||||
TSlaveCommand.command = cmnd;
|
||||
TSlaveCommand.parameter = param;
|
||||
char buffer[sizeof(TSlaveCommand)+2];
|
||||
buffer[0] = CMND_START;
|
||||
memcpy(&buffer[1], &TSlaveCommand, sizeof(TSlaveCommand));
|
||||
buffer[sizeof(TSlaveCommand)+1] = CMND_END;
|
||||
|
||||
TasmotaSlave_Serial->flush(); // Theo 20200502
|
||||
|
||||
for (uint8_t ca = 0; ca < sizeof(buffer); ca++) {
|
||||
TasmotaSlave_Serial->write(buffer[ca]);
|
||||
}
|
||||
}
|
||||
|
||||
#define D_PRFX_SLAVE "Slave"
|
||||
#define D_CMND_SLAVE_RESET "Reset"
|
||||
#define D_CMND_SLAVE_SEND "Send"
|
||||
|
||||
const char kTasmotaSlaveCommands[] PROGMEM = D_PRFX_SLAVE "|"
|
||||
D_CMND_SLAVE_RESET "|" D_CMND_SLAVE_SEND;
|
||||
|
||||
void (* const TasmotaSlaveCommand[])(void) PROGMEM = {
|
||||
&CmndTasmotaSlaveReset, &CmndTasmotaSlaveSend };
|
||||
|
||||
void CmndTasmotaSlaveReset(void)
|
||||
{
|
||||
TasmotaSlave_Reset();
|
||||
TSlave.type = false; // Force redetection
|
||||
TSlave.waitstate = 7; // give it at least 3 seconds to restart from bootloader
|
||||
TSlave.unsupported = false; // Reset unsupported flag
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
void CmndTasmotaSlaveSend(void)
|
||||
{
|
||||
if (0 < XdrvMailbox.data_len) {
|
||||
TasmotaSlave_sendCmnd(CMND_SLAVE_SEND, XdrvMailbox.data_len);
|
||||
TasmotaSlave_Serial->write(char(PARAM_DATA_START));
|
||||
for (uint8_t idx = 0; idx < XdrvMailbox.data_len; idx++) {
|
||||
TasmotaSlave_Serial->write(XdrvMailbox.data[idx]);
|
||||
}
|
||||
TasmotaSlave_Serial->write(char(PARAM_DATA_END));
|
||||
}
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
void TasmotaSlave_ProcessIn(void)
|
||||
{
|
||||
uint8_t cmnd = TasmotaSlave_Serial->read();
|
||||
switch (cmnd) {
|
||||
case CMND_START:
|
||||
TasmotaSlave_waitForSerialData(sizeof(TSlaveCommand),50);
|
||||
uint8_t buffer[sizeof(TSlaveCommand)];
|
||||
for (uint8_t idx = 0; idx < sizeof(TSlaveCommand); idx++) {
|
||||
buffer[idx] = TasmotaSlave_Serial->read();
|
||||
}
|
||||
TasmotaSlave_Serial->read(); // read trailing byte of command
|
||||
memcpy(&TSlaveCommand, &buffer, sizeof(TSlaveCommand));
|
||||
char inbuf[TSlaveCommand.parameter+1];
|
||||
TasmotaSlave_waitForSerialData(TSlaveCommand.parameter, 50);
|
||||
TasmotaSlave_Serial->read(); // Read leading byte
|
||||
for (uint8_t idx = 0; idx < TSlaveCommand.parameter; idx++) {
|
||||
inbuf[idx] = TasmotaSlave_Serial->read();
|
||||
}
|
||||
TasmotaSlave_Serial->read(); // Read trailing byte
|
||||
inbuf[TSlaveCommand.parameter] = '\0';
|
||||
|
||||
if (CMND_PUBLISH_TELE == TSlaveCommand.command) { // We need to publish stat/ with incoming stream as content
|
||||
Response_P(PSTR("{\"TasmotaSlave\":"));
|
||||
ResponseAppend_P("%s", inbuf);
|
||||
ResponseJsonEnd();
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data);
|
||||
XdrvRulesProcess();
|
||||
}
|
||||
if (CMND_EXECUTE_CMND == TSlaveCommand.command) { // We need to execute the incoming command
|
||||
ExecuteCommand(inbuf, SRC_IGNORE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xdrv31(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
switch (function) {
|
||||
case FUNC_EVERY_100_MSECOND:
|
||||
if (TSlave.type) {
|
||||
if (TasmotaSlave_Serial->available()) {
|
||||
TasmotaSlave_ProcessIn();
|
||||
}
|
||||
if (TSlaveSettings.features.func_every_100_msecond) {
|
||||
TasmotaSlave_sendCmnd(CMND_FUNC_EVERY_100_MSECOND, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
if ((TSlave.type) && (TSlaveSettings.features.func_every_second)) {
|
||||
TasmotaSlave_sendCmnd(CMND_FUNC_EVERY_SECOND, 0);
|
||||
}
|
||||
TasmotaSlave_Init();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
if ((TSlave.type) && (TSlaveSettings.features.func_json_append)) {
|
||||
TasmotaSlave_Show();
|
||||
}
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
result = DecodeCommand(kTasmotaSlaveCommands, TasmotaSlaveCommand);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_TASMOTA_SLAVE
|
|
@ -1331,7 +1331,7 @@ void ThermostatGetLocalSensor(uint8_t ctr_output) {
|
|||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonObject& root = jsonBuffer.parseObject((const char*)mqtt_data);
|
||||
if (root.success()) {
|
||||
const char* value_c = root["THERMOSTAT_SENSOR_NAME"]["Temperature"];
|
||||
const char* value_c = root[THERMOSTAT_SENSOR_NAME]["Temperature"];
|
||||
if (value_c != NULL && strlen(value_c) > 0 && (isdigit(value_c[0]) || (value_c[0] == '-' && isdigit(value_c[1])) ) ) {
|
||||
int16_t value = (int16_t)(CharToFloat(value_c) * 10);
|
||||
if ( (value >= -1000)
|
||||
|
|
|
@ -0,0 +1,470 @@
|
|||
/*
|
||||
xdrv_40_telegram.ino - telegram for Tasmota
|
||||
|
||||
Copyright (C) 2020 Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_TELEGRAM
|
||||
/*********************************************************************************************\
|
||||
* Telegram bot
|
||||
*
|
||||
* Supported commands:
|
||||
* TmToken <token> - Add your BotFather created bot token (default none)
|
||||
* TmChatId <chat_id> - Add your BotFather created bot chat id (default none)
|
||||
* TmPoll <seconds> - Telegram receive poll time (default 10 seconds)
|
||||
* TmState 0 - Disable telegram sending (default)
|
||||
* TmState 1 - Enable telegram sending
|
||||
* TmState 2 - Disable telegram listener (default)
|
||||
* TmState 3 - Enable telegram listener
|
||||
* TmState 4 - Disable telegram response echo (default)
|
||||
* TmState 5 - Enable telegram response echo
|
||||
* TmSend <data> - If telegram sending is enabled AND a chat id is present then send data
|
||||
*
|
||||
* Tested with defines
|
||||
* #define USE_TELEGRAM // Support for Telegram protocol
|
||||
* #define USE_TELEGRAM_FINGERPRINT "\xB2\x72\x47\xA6\x69\x8C\x3C\x69\xF9\x58\x6C\xF3\x60\x02\xFB\x83\xFA\x8B\x1F\x23" // Telegram api.telegram.org TLS public key fingerpring
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XDRV_40 40
|
||||
|
||||
#define TELEGRAM_SEND_RETRY 4 // Retries
|
||||
#define TELEGRAM_LOOP_WAIT 10 // Seconds
|
||||
|
||||
#ifdef USE_MQTT_TLS_CA_CERT
|
||||
static const uint32_t tls_rx_size = 2048; // since Telegram CA is bigger than 1024 bytes, we need to increase rx buffer
|
||||
static const uint32_t tls_tx_size = 1024;
|
||||
#else
|
||||
static const uint32_t tls_rx_size = 1024;
|
||||
static const uint32_t tls_tx_size = 1024;
|
||||
#endif
|
||||
|
||||
#include "WiFiClientSecureLightBearSSL.h"
|
||||
BearSSL::WiFiClientSecure_light *telegramClient = nullptr;
|
||||
|
||||
static const uint8_t Telegram_Fingerprint[] PROGMEM = USE_TELEGRAM_FINGERPRINT;
|
||||
|
||||
struct {
|
||||
String message[3][6]; // amount of messages read per time (update_id, name_id, name, lastname, chat_id, text)
|
||||
uint8_t state = 0;
|
||||
uint8_t index = 0;
|
||||
uint8_t retry = 0;
|
||||
uint8_t poll = TELEGRAM_LOOP_WAIT;
|
||||
uint8_t wait = 0;
|
||||
bool send_enable = false;
|
||||
bool recv_enable = false;
|
||||
bool echo_enable = false;
|
||||
bool recv_busy = false;
|
||||
} Telegram;
|
||||
|
||||
bool TelegramInit(void) {
|
||||
bool init_done = false;
|
||||
if (strlen(SettingsText(SET_TELEGRAM_TOKEN))) {
|
||||
if (!telegramClient) {
|
||||
telegramClient = new BearSSL::WiFiClientSecure_light(tls_rx_size, tls_tx_size);
|
||||
#ifdef USE_MQTT_TLS_CA_CERT
|
||||
telegramClient->setTrustAnchor(&GoDaddyCAG2_TA);
|
||||
#else
|
||||
telegramClient->setPubKeyFingerprint(Telegram_Fingerprint, Telegram_Fingerprint, false); // check server fingerprint
|
||||
#endif
|
||||
|
||||
Telegram.message[0][0]="0"; // Number of received messages
|
||||
Telegram.message[1][0]="";
|
||||
Telegram.message[0][1]="0"; // Code of last read Message
|
||||
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("TGM: Started"));
|
||||
}
|
||||
|
||||
init_done = true;
|
||||
}
|
||||
return init_done;
|
||||
}
|
||||
|
||||
String TelegramConnectToTelegram(String command) {
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Cmnd %s"), command.c_str());
|
||||
|
||||
if (!TelegramInit()) { return ""; }
|
||||
|
||||
String response = "";
|
||||
uint32_t tls_connect_time = millis();
|
||||
|
||||
if (telegramClient->connect("api.telegram.org", 443)) {
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Connected in %d ms, max ThunkStack used %d"), millis() - tls_connect_time, telegramClient->getMaxThunkStackUse());
|
||||
|
||||
telegramClient->println("GET /"+command);
|
||||
|
||||
String a = "";
|
||||
char c;
|
||||
int ch_count=0;
|
||||
uint32_t now = millis();
|
||||
bool avail = false;
|
||||
while (millis() -now < 1500) {
|
||||
while (telegramClient->available()) {
|
||||
char c = telegramClient->read();
|
||||
if (ch_count < 700) {
|
||||
response = response + c;
|
||||
ch_count++;
|
||||
}
|
||||
avail = true;
|
||||
}
|
||||
if (avail) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
telegramClient->stop();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
void TelegramGetUpdates(String offset) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: getUpdates"));
|
||||
|
||||
if (!TelegramInit()) { return; }
|
||||
|
||||
String _token = SettingsText(SET_TELEGRAM_TOKEN);
|
||||
String command = "bot" + _token + "/getUpdates?offset=" + offset;
|
||||
String response = TelegramConnectToTelegram(command); //recieve reply from telegram.org
|
||||
|
||||
// {"ok":true,"result":[]}
|
||||
// or
|
||||
// {"ok":true,"result":[
|
||||
// {"update_id":973125394,
|
||||
// "message":{"message_id":25,
|
||||
// "from":{"id":139920293,"is_bot":false,"first_name":"Theo","last_name":"Arends","username":"tjatja","language_code":"nl"},
|
||||
// "chat":{"id":139920293,"first_name":"Theo","last_name":"Arends","username":"tjatja","type":"private"},
|
||||
// "date":1591877503,
|
||||
// "text":"M1"
|
||||
// }
|
||||
// },
|
||||
// {"update_id":973125395,
|
||||
// "message":{"message_id":26,
|
||||
// "from":{"id":139920293,"is_bot":false,"first_name":"Theo","last_name":"Arends","username":"tjatja","language_code":"nl"},
|
||||
// "chat":{"id":139920293,"first_name":"Theo","last_name":"Arends","username":"tjatja","type":"private"},
|
||||
// "date":1591877508,
|
||||
// "text":"M2"
|
||||
// }
|
||||
// }
|
||||
// ]}
|
||||
// or
|
||||
// {"ok":true,"result":[
|
||||
// {"update_id":973125396,
|
||||
// "message":{"message_id":29,
|
||||
// "from":{"id":139920293,"is_bot":false,"first_name":"Theo","last_name":"Arends","username":"tjatja","language_code":"nl"},
|
||||
// "chat":{"id":139920293,"first_name":"Theo","last_name":"Arends","username":"tjatja","type":"private"},
|
||||
// "date":1591879753,
|
||||
// "text":"/power toggle",
|
||||
// "entities":[{"offset":0,"length":6,"type":"bot_command"}]
|
||||
// }
|
||||
// }
|
||||
// ]}
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str());
|
||||
|
||||
// parsing of reply from Telegram into separate received messages
|
||||
int i = 0; //messages received counter
|
||||
if (response != "") {
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Sent Update request messages up to %s"), offset.c_str());
|
||||
|
||||
String a = "";
|
||||
int ch_count = 0;
|
||||
String c;
|
||||
for (uint32_t n = 1; n < response.length() +1; n++) { //Search for each message start
|
||||
ch_count++;
|
||||
c = response.substring(n -1, n);
|
||||
a = a + c;
|
||||
if (ch_count > 8) {
|
||||
if (a.substring(ch_count -9) == "update_id") {
|
||||
if (i > 1) { break; }
|
||||
Telegram.message[i][0] = a.substring(0, ch_count -11);
|
||||
a = a.substring(ch_count-11);
|
||||
i++;
|
||||
ch_count = 11;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (1 == i) {
|
||||
Telegram.message[i][0] = a.substring(0, ch_count); //Assign of parsed message into message matrix if only 1 message)
|
||||
}
|
||||
if (i > 1) { i = i -1; }
|
||||
}
|
||||
//check result of parsing process
|
||||
if (response == "") {
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Failed to update"));
|
||||
return;
|
||||
}
|
||||
if (0 == i) {
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: No new messages"));
|
||||
Telegram.message[0][0] = "0";
|
||||
} else {
|
||||
Telegram.message[0][0] = String(i); //returns how many messages are in the array
|
||||
for (int b = 1; b < i+1; b++) {
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Msg %d %s"), b, Telegram.message[b][0].c_str());
|
||||
}
|
||||
|
||||
TelegramAnalizeMessage();
|
||||
}
|
||||
}
|
||||
|
||||
void TelegramAnalizeMessage(void) {
|
||||
for (uint32_t i = 1; i < Telegram.message[0][0].toInt() +1; i++) {
|
||||
Telegram.message[i][5] = "";
|
||||
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonObject &root = jsonBuffer.parseObject(Telegram.message[i][0]);
|
||||
if (root.success()) {
|
||||
Telegram.message[i][0] = root["update_id"].as<String>();
|
||||
Telegram.message[i][1] = root["message"]["from"]["id"].as<String>();
|
||||
Telegram.message[i][2] = root["message"]["from"]["first_name"].as<String>();
|
||||
Telegram.message[i][3] = root["message"]["from"]["last_name"].as<String>();
|
||||
Telegram.message[i][4] = root["message"]["chat"]["id"].as<String>();
|
||||
Telegram.message[i][5] = root["message"]["text"].as<String>();
|
||||
}
|
||||
|
||||
int id = Telegram.message[Telegram.message[0][0].toInt()][0].toInt() +1;
|
||||
Telegram.message[0][1] = id; // Write id of last read message
|
||||
|
||||
for (int j = 0; j < 6; j++) {
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Parsed%d \"%s\""), j, Telegram.message[i][j].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TelegramSendMessage(String chat_id, String text) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: sendMessage"));
|
||||
|
||||
if (!TelegramInit()) { return false; }
|
||||
|
||||
bool sent = false;
|
||||
if (text != "") {
|
||||
String _token = SettingsText(SET_TELEGRAM_TOKEN);
|
||||
String command = "bot" + _token + "/sendMessage?chat_id=" + chat_id + "&text=" + text;
|
||||
String response = TelegramConnectToTelegram(command);
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str());
|
||||
|
||||
if (response.startsWith("{\"ok\":true")) {
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Message sent"));
|
||||
sent = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
/*
|
||||
void TelegramSendGetMe(void) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: getMe"));
|
||||
|
||||
if (!TelegramInit()) { return; }
|
||||
|
||||
String _token = SettingsText(SET_TELEGRAM_TOKEN);
|
||||
String command = "bot" + _token + "/getMe";
|
||||
String response = TelegramConnectToTelegram(command);
|
||||
|
||||
// {"ok":true,"result":{"id":1179906608,"is_bot":true,"first_name":"Tasmota","username":"tasmota_bot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}}
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str());
|
||||
}
|
||||
*/
|
||||
|
||||
String TelegramExecuteCommand(const char *svalue) {
|
||||
String response = "";
|
||||
|
||||
uint32_t curridx = web_log_index;
|
||||
ExecuteCommand(svalue, SRC_CHAT);
|
||||
if (web_log_index != curridx) {
|
||||
uint32_t counter = curridx;
|
||||
response = F("{");
|
||||
bool cflg = false;
|
||||
do {
|
||||
char* tmp;
|
||||
size_t len;
|
||||
GetLog(counter, &tmp, &len);
|
||||
if (len) {
|
||||
// [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}]
|
||||
char* JSON = (char*)memchr(tmp, '{', len);
|
||||
if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O])
|
||||
size_t JSONlen = len - (JSON - tmp);
|
||||
if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); }
|
||||
char stemp[JSONlen];
|
||||
strlcpy(stemp, JSON +1, JSONlen -2);
|
||||
if (cflg) { response += F(","); }
|
||||
response += stemp;
|
||||
cflg = true;
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
counter &= 0xFF;
|
||||
if (!counter) counter++; // Skip 0 as it is not allowed
|
||||
} while (counter != web_log_index);
|
||||
response += F("}");
|
||||
} else {
|
||||
response = F("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}");
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
void TelegramLoop(void) {
|
||||
if (!global_state.network_down && (Telegram.recv_enable || Telegram.echo_enable)) {
|
||||
switch (Telegram.state) {
|
||||
case 0:
|
||||
TelegramInit();
|
||||
Telegram.state++;
|
||||
break;
|
||||
case 1:
|
||||
TelegramGetUpdates(Telegram.message[0][1]); // launch API GetUpdates up to xxx message
|
||||
Telegram.index = 1;
|
||||
Telegram.retry = TELEGRAM_SEND_RETRY;
|
||||
Telegram.state++;
|
||||
break;
|
||||
case 2:
|
||||
if (Telegram.echo_enable) {
|
||||
if (Telegram.retry && (Telegram.index < Telegram.message[0][0].toInt() + 1)) {
|
||||
if (TelegramSendMessage(Telegram.message[Telegram.index][4], Telegram.message[Telegram.index][5])) {
|
||||
Telegram.index++;
|
||||
Telegram.retry = TELEGRAM_SEND_RETRY;
|
||||
} else {
|
||||
Telegram.retry--;
|
||||
}
|
||||
} else {
|
||||
Telegram.message[0][0] = ""; // All messages have been replied - reset new messages
|
||||
Telegram.wait = Telegram.poll;
|
||||
Telegram.state++;
|
||||
}
|
||||
} else {
|
||||
if (Telegram.message[0][0].toInt() && (Telegram.message[Telegram.index][5].length() > 0)) {
|
||||
String logging = TelegramExecuteCommand(Telegram.message[Telegram.index][5].c_str());
|
||||
if (logging.length() > 0) {
|
||||
TelegramSendMessage(Telegram.message[Telegram.index][4], logging);
|
||||
}
|
||||
}
|
||||
Telegram.message[0][0] = ""; // All messages have been replied - reset new messages
|
||||
Telegram.wait = Telegram.poll;
|
||||
Telegram.state++;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (Telegram.wait) {
|
||||
Telegram.wait--;
|
||||
} else {
|
||||
Telegram.state = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Commands
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define D_CMND_TMSTATE "State"
|
||||
#define D_CMND_TMPOLL "Poll"
|
||||
#define D_CMND_TMSEND "Send"
|
||||
#define D_CMND_TMTOKEN "Token"
|
||||
#define D_CMND_TMCHATID "ChatId"
|
||||
|
||||
const char kTelegramCommands[] PROGMEM = "Tm|" // Prefix
|
||||
D_CMND_TMSTATE "|" D_CMND_TMPOLL "|" D_CMND_TMTOKEN "|" D_CMND_TMCHATID "|" D_CMND_TMSEND;
|
||||
|
||||
void (* const TelegramCommand[])(void) PROGMEM = {
|
||||
&CmndTmState, &CmndTmPoll, &CmndTmToken, &CmndTmChatId, &CmndTmSend };
|
||||
|
||||
void CmndTmState(void) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) {
|
||||
switch (XdrvMailbox.payload) {
|
||||
case 0: // Off
|
||||
case 1: // On
|
||||
Telegram.send_enable = XdrvMailbox.payload &1;
|
||||
break;
|
||||
case 2: // Off
|
||||
case 3: // On
|
||||
Telegram.recv_enable = XdrvMailbox.payload &1;
|
||||
break;
|
||||
case 4: // Off
|
||||
case 5: // On
|
||||
Telegram.echo_enable = XdrvMailbox.payload &1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":{\"Send\":\"%s\",\"Receive\":\"%s\",\"Echo\":\"%s\"}}"),
|
||||
XdrvMailbox.command, GetStateText(Telegram.send_enable), GetStateText(Telegram.recv_enable), GetStateText(Telegram.echo_enable));
|
||||
}
|
||||
|
||||
void CmndTmPoll(void) {
|
||||
if ((XdrvMailbox.payload >= 4) && (XdrvMailbox.payload <= 300)) {
|
||||
Telegram.poll = XdrvMailbox.payload;
|
||||
if (Telegram.poll < Telegram.wait) {
|
||||
Telegram.wait = Telegram.poll;
|
||||
}
|
||||
}
|
||||
ResponseCmndNumber(Telegram.poll);
|
||||
}
|
||||
|
||||
void CmndTmToken(void) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
SettingsUpdateText(SET_TELEGRAM_TOKEN, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data);
|
||||
}
|
||||
ResponseCmndChar(SettingsText(SET_TELEGRAM_TOKEN));
|
||||
}
|
||||
|
||||
void CmndTmChatId(void) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
SettingsUpdateText(SET_TELEGRAM_CHATID, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data);
|
||||
}
|
||||
ResponseCmndChar(SettingsText(SET_TELEGRAM_CHATID));
|
||||
}
|
||||
|
||||
void CmndTmSend(void) {
|
||||
if (!Telegram.send_enable || !strlen(SettingsText(SET_TELEGRAM_CHATID))) {
|
||||
ResponseCmndChar(D_JSON_FAILED);
|
||||
return;
|
||||
}
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
String message = XdrvMailbox.data;
|
||||
String chat_id = SettingsText(SET_TELEGRAM_CHATID);
|
||||
if (!TelegramSendMessage(chat_id, message)) {
|
||||
ResponseCmndChar(D_JSON_FAILED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xdrv40(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
switch (function) {
|
||||
case FUNC_EVERY_SECOND:
|
||||
TelegramLoop();
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
result = DecodeCommand(kTelegramCommands, TelegramCommand);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif // USE_TELEGRAM
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue