refact AUTH module

This commit is contained in:
2025-06-08 00:29:35 +01:00
parent d5ed5a31b9
commit 71b6cb7878
16 changed files with 291 additions and 2896 deletions

View File

@@ -1,4 +1,4 @@
set(srcs "src/auth.c" "src/rc522_2.c" "src/wiegand.c" "src/main_wiegand.c")
set(srcs "src/auth.c" "src/wiegand.c" "src/wiegand_reader.c")
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "include"

12
components/auth/include/auth.h Normal file → Executable file
View File

@@ -1,9 +1,17 @@
#ifndef AUTH_H
#define AUTH_H
#pragma once
#include <stdbool.h>
void auth_set_enable(bool value);
bool auth_get_enable(void);
void auth_init(void); // Iniciar serviço
void auth_set_enabled(bool enabled); // Habilitar ou desabilitar leitura
bool auth_is_enabled(void); // Verificar estado
bool auth_add_tag(const char *tag); // Adiciona uma tag válida
bool auth_remove_tag(const char *tag); // Remove tag
bool auth_tag_exists(const char *tag); // Verifica se tag é válida
void auth_list_tags(void); // Opcional: listar no log
#endif // AUTH_H

View File

@@ -1,333 +0,0 @@
/*
* rc522.h
*
* Created on:
* Author:
*/
#ifndef MAIN_RC522_H_
#define MAIN_RC522_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/spi_master.h"
#include "soc/gpio_struct.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#include <stdint.h>
#define null 0
#define F(x) x
#define printfln(x) printf(x)
#define PIN_NUM_MISO GPIO_NUM_27
#define PIN_NUM_MOSI GPIO_NUM_14
#define PIN_NUM_CLK GPIO_NUM_12
#define PIN_NUM_CS GPIO_NUM_18
#define PIN_NUM_RST GPIO_NUM_35
//#define PIN_NUM_MISO 25
//#define PIN_NUM_MOSI 23
//#define PIN_NUM_CLK 19
//#define PIN_NUM_CS 22
//#define PIN_NUM_RST 14
#define MFRC522_SPICLOCK SPI_CLOCK_DIV4 // MFRC522 accept upto 10MHz
typedef uint8_t byte;
// Firmware data for self-test
// Reference values based on firmware version
// Hint: if needed, you can remove unused self-test data to save flash memory
//
// Version 0.0 (0x90)
// Philips Semiconductors; Preliminary Specification Revision 2.0 - 01 August 2005; 16.1 self-test
// MFRC522 registers. Described in chapter 9 of the datasheet.
// When using SPI all addresses are shifted one bit left in the "SPI address byte" (section 8.1.2.3)
typedef enum PCD_Register {
// Page 0: Command and status
// 0x00 // reserved for future use
CommandReg = 0x01 << 1, // starts and stops command execution
ComIEnReg = 0x02 << 1, // enable and disable interrupt request control bits
DivIEnReg = 0x03 << 1, // enable and disable interrupt request control bits
ComIrqReg = 0x04 << 1, // interrupt request bits
DivIrqReg = 0x05 << 1, // interrupt request bits
ErrorReg = 0x06 << 1, // error bits showing the error status of the last command executed
Status1Reg = 0x07 << 1, // communication status bits
Status2Reg = 0x08 << 1, // receiver and transmitter status bits
FIFODataReg = 0x09 << 1, // input and output of 64 byte FIFO buffer
FIFOLevelReg = 0x0A << 1, // number of bytes stored in the FIFO buffer
WaterLevelReg = 0x0B << 1, // level for FIFO underflow and overflow warning
ControlReg = 0x0C << 1, // miscellaneous control registers
BitFramingReg = 0x0D << 1, // adjustments for bit-oriented frames
CollReg = 0x0E << 1, // bit position of the first bit-collision detected on the RF interface
// 0x0F // reserved for future use
// Page 1: Command
// 0x10 // reserved for future use
ModeReg = 0x11 << 1, // defines general modes for transmitting and receiving
TxModeReg = 0x12 << 1, // defines transmission data rate and framing
RxModeReg = 0x13 << 1, // defines reception data rate and framing
TxControlReg = 0x14 << 1, // controls the logical behavior of the antenna driver pins TX1 and TX2
TxASKReg = 0x15 << 1, // controls the setting of the transmission modulation
TxSelReg = 0x16 << 1, // selects the internal sources for the antenna driver
RxSelReg = 0x17 << 1, // selects internal receiver settings
RxThresholdReg = 0x18 << 1, // selects thresholds for the bit decoder
DemodReg = 0x19 << 1, // defines demodulator settings
// 0x1A // reserved for future use
// 0x1B // reserved for future use
MfTxReg = 0x1C << 1, // controls some MIFARE communication transmit parameters
MfRxReg = 0x1D << 1, // controls some MIFARE communication receive parameters
// 0x1E // reserved for future use
SerialSpeedReg = 0x1F << 1, // selects the speed of the serial UART interface
// Page 2: Configuration
// 0x20 // reserved for future use
CRCResultRegH = 0x21 << 1, // shows the MSB and LSB values of the CRC calculation
CRCResultRegL = 0x22 << 1,
// 0x23 // reserved for future use
ModWidthReg = 0x24 << 1, // controls the ModWidth setting?
// 0x25 // reserved for future use
RFCfgReg = 0x26 << 1, // configures the receiver gain
GsNReg = 0x27 << 1, // selects the conductance of the antenna driver pins TX1 and TX2 for modulation
CWGsPReg = 0x28 << 1, // defines the conductance of the p-driver output during periods of no modulation
ModGsPReg = 0x29 << 1, // defines the conductance of the p-driver output during periods of modulation
TModeReg = 0x2A << 1, // defines settings for the internal timer
TPrescalerReg = 0x2B << 1, // the lower 8 bits of the TPrescaler value. The 4 high bits are in TModeReg.
TReloadRegH = 0x2C << 1, // defines the 16-bit timer reload value
TReloadRegL = 0x2D << 1,
TCounterValueRegH = 0x2E << 1, // shows the 16-bit timer value
TCounterValueRegL = 0x2F << 1,
// Page 3: Test Registers
// 0x30 // reserved for future use
TestSel1Reg = 0x31 << 1, // general test signal configuration
TestSel2Reg = 0x32 << 1, // general test signal configuration
TestPinEnReg = 0x33 << 1, // enables pin output driver on pins D1 to D7
TestPinValueReg = 0x34 << 1, // defines the values for D1 to D7 when it is used as an I/O bus
TestBusReg = 0x35 << 1, // shows the status of the internal test bus
AutoTestReg = 0x36 << 1, // controls the digital self-test
VersionReg = 0x37 << 1, // shows the software version
AnalogTestReg = 0x38 << 1, // controls the pins AUX1 and AUX2
TestDAC1Reg = 0x39 << 1, // defines the test value for TestDAC1
TestDAC2Reg = 0x3A << 1, // defines the test value for TestDAC2
TestADCReg = 0x3B << 1 // shows the value of ADC I and Q channels
// 0x3C // reserved for production tests
// 0x3D // reserved for production tests
// 0x3E // reserved for production tests
// 0x3F // reserved for production tests
}PCD_Register;
// MFRC522 commands. Described in chapter 10 of the datasheet.
typedef enum PCD_Command {
PCD_Idle = 0x00, // no action, cancels current command execution
PCD_Mem = 0x01, // stores 25 bytes into the internal buffer
PCD_GenerateRandomID = 0x02, // generates a 10-byte random ID number
PCD_CalcCRC = 0x03, // activates the CRC coprocessor or performs a self-test
PCD_Transmit = 0x04, // transmits data from the FIFO buffer
PCD_NoCmdChange = 0x07, // no command change, can be used to modify the CommandReg register bits without affecting the command, for example, the PowerDown bit
PCD_Receive = 0x08, // activates the receiver circuits
PCD_Transceive = 0x0C, // transmits data from FIFO buffer to antenna and automatically activates the receiver after transmission
PCD_MFAuthent = 0x0E, // performs the MIFARE standard authentication as a reader
PCD_SoftReset = 0x0F // resets the MFRC522
}PCD_Command;
// MFRC522 RxGain[2:0] masks, defines the receiver's signal voltage gain factor (on the PCD).
// Described in 9.3.3.6 / table 98 of the datasheet at http://www.nxp.com/documents/data_sheet/MFRC522.pdf
typedef enum PCD_RxGain {
RxGain_18dB = 0x00 << 4, // 000b - 18 dB, minimum
RxGain_23dB = 0x01 << 4, // 001b - 23 dB
RxGain_18dB_2 = 0x02 << 4, // 010b - 18 dB, it seems 010b is a duplicate for 000b
RxGain_23dB_2 = 0x03 << 4, // 011b - 23 dB, it seems 011b is a duplicate for 001b
RxGain_33dB = 0x04 << 4, // 100b - 33 dB, average, and typical default
RxGain_38dB = 0x05 << 4, // 101b - 38 dB
RxGain_43dB = 0x06 << 4, // 110b - 43 dB
RxGain_48dB = 0x07 << 4, // 111b - 48 dB, maximum
RxGain_min = 0x00 << 4, // 000b - 18 dB, minimum, convenience for RxGain_18dB
RxGain_avg = 0x04 << 4, // 100b - 33 dB, average, convenience for RxGain_33dB
RxGain_max = 0x07 << 4 // 111b - 48 dB, maximum, convenience for RxGain_48dB
}PCD_RxGain;
// Commands sent to the PICC.
typedef enum PICC_Command {
// The commands used by the PCD to manage communication with several PICCs (ISO 14443-3, Type A, section 6.4)
PICC_CMD_REQA = 0x26, // REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame.
PICC_CMD_WUPA = 0x52, // Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame.
PICC_CMD_CT = 0x88, // Cascade Tag. Not really a command, but used during anti collision.
PICC_CMD_SEL_CL1 = 0x93, // Anti collision/Select, Cascade Level 1
PICC_CMD_SEL_CL2 = 0x95, // Anti collision/Select, Cascade Level 2
PICC_CMD_SEL_CL3 = 0x97, // Anti collision/Select, Cascade Level 3
PICC_CMD_HLTA = 0x50, // HaLT command, Type A. Instructs an ACTIVE PICC to go to state HALT.
PICC_CMD_RATS = 0xE0, // Request command for Answer To Reset.
// The commands used for MIFARE Classic (from http://www.mouser.com/ds/2/302/MF1S503x-89574.pdf, Section 9)
// Use PCD_MFAuthent to authenticate access to a sector, then use these commands to read/write/modify the blocks on the sector.
// The read/write commands can also be used for MIFARE Ultralight.
PICC_CMD_MF_AUTH_KEY_A = 0x60, // Perform authentication with Key A
PICC_CMD_MF_AUTH_KEY_B = 0x61, // Perform authentication with Key B
PICC_CMD_MF_READ = 0x30, // Reads one 16 byte block from the authenticated sector of the PICC. Also used for MIFARE Ultralight.
PICC_CMD_MF_WRITE = 0xA0, // Writes one 16 byte block to the authenticated sector of the PICC. Called "COMPATIBILITY WRITE" for MIFARE Ultralight.
PICC_CMD_MF_DECREMENT = 0xC0, // Decrements the contents of a block and stores the result in the internal data register.
PICC_CMD_MF_INCREMENT = 0xC1, // Increments the contents of a block and stores the result in the internal data register.
PICC_CMD_MF_RESTORE = 0xC2, // Reads the contents of a block into the internal data register.
PICC_CMD_MF_TRANSFER = 0xB0, // Writes the contents of the internal data register to a block.
// The commands used for MIFARE Ultralight (from http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf, Section 8.6)
// The PICC_CMD_MF_READ and PICC_CMD_MF_WRITE can also be used for MIFARE Ultralight.
PICC_CMD_UL_WRITE = 0xA2 // Writes one 4 byte page to the PICC.
}PICC_Command;
// MIFARE constants that does not fit anywhere else
enum MIFARE_Misc {
MF_ACK = 0xA, // The MIFARE Classic uses a 4 bit ACK/NAK. Any other value than 0xA is NAK.
MF_KEY_SIZE = 6 // A Mifare Crypto1 key is 6 bytes.
};
// PICC types we can detect. Remember to update PICC_GetTypeName() if you add more.
// last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered
typedef enum PICC_Type {
PICC_TYPE_UNKNOWN ,
PICC_TYPE_ISO_14443_4 , // PICC compliant with ISO/IEC 14443-4
PICC_TYPE_ISO_18092 , // PICC compliant with ISO/IEC 18092 (NFC)
PICC_TYPE_MIFARE_MINI , // MIFARE Classic protocol, 320 bytes
PICC_TYPE_MIFARE_1K , // MIFARE Classic protocol, 1KB
PICC_TYPE_MIFARE_4K , // MIFARE Classic protocol, 4KB
PICC_TYPE_MIFARE_UL , // MIFARE Ultralight or Ultralight C
PICC_TYPE_MIFARE_PLUS , // MIFARE Plus
PICC_TYPE_MIFARE_DESFIRE, // MIFARE DESFire
PICC_TYPE_TNP3XXX , // Only mentioned in NXP AN 10833 MIFARE Type Identification Procedure
PICC_TYPE_NOT_COMPLETE = 0xff // SAK indicates UID is not complete.
}PICC_Type;
// Return codes from the functions in this class. Remember to update GetStatusCodeName() if you add more.
// last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered
typedef enum StatusCode {
STATUS_OK , // Success
STATUS_ERROR , // Error in communication
STATUS_COLLISION , // Collission detected
STATUS_TIMEOUT , // Timeout in communication.
STATUS_NO_ROOM , // A buffer is not big enough.
STATUS_INTERNAL_ERROR , // Internal error in the code. Should not happen ;-)
STATUS_INVALID , // Invalid argument.
STATUS_CRC_WRONG , // The CRC_A does not match
STATUS_MIFARE_NACK = 0xff // A MIFARE PICC responded with NAK.
}StatusCode;
// A struct used for passing the UID of a PICC.
typedef struct {
byte size; // Number of bytes in the UID. 4, 7 or 10.
byte uidByte[10];
byte sak; // The SAK (Select acknowledge) byte returned from the PICC after successful selection.
} Uid;
// A struct used for passing a MIFARE Crypto1 key
typedef struct {
byte keyByte[MF_KEY_SIZE];
} MIFARE_Key;
/////////////////////////////////////////////////////////////////////////////////////
// Basic interface functions for communicating with the MFRC522
/////////////////////////////////////////////////////////////////////////////////////
void PCD_WriteRegister(uint8_t Register , uint8_t value);
void PCD_WriteRegisterMany(uint8_t Register, uint8_t count, uint8_t *values);
uint8_t PCD_ReadRegister(uint8_t Register);
void PCD_ReadRegisterMany(uint8_t Register,uint8_t count,uint8_t *values,uint8_t rxAlign);
void PCD_SetRegisterBitMask(uint8_t reg, byte mask);
void PCD_ClearRegisterBitMask(uint8_t reg, byte mask);
StatusCode PCD_CalculateCRC(byte *data, byte length, byte *result);
/////////////////////////////////////////////////////////////////////////////////////
// Functions for manipulating the MFRC522
/////////////////////////////////////////////////////////////////////////////////////
void PCD_Init();
void PCD_Reset();
void PCD_AntennaOn();
void PCD_AntennaOff();
byte PCD_GetAntennaGain();
void PCD_SetAntennaGain(byte mask);
bool PCD_PerformSelfTest();
/////////////////////////////////////////////////////////////////////////////////////
// Power control functions
/////////////////////////////////////////////////////////////////////////////////////
void PCD_SoftPowerDown();
void PCD_SoftPowerUp();
/////////////////////////////////////////////////////////////////////////////////////
// Functions for communicating with PICCs
/////////////////////////////////////////////////////////////////////////////////////
uint8_t PCD_TransceiveData(byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits, byte rxAlign, bool checkCRC);
uint8_t PCD_CommunicateWithPICC(byte command, byte waitIRq, byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits, byte rxAlign, bool checkCRC);
uint8_t PICC_RequestA(byte *bufferATQA, byte *bufferSize);
uint8_t PICC_WakeupA(byte *bufferATQA, byte *bufferSize);
uint8_t PICC_REQA_or_WUPA(uint8_t command,uint8_t *bufferATQA,uint8_t *bufferSize);
StatusCode PICC_Select(Uid *uid, byte validBits);
StatusCode PICC_HaltA();
/////////////////////////////////////////////////////////////////////////////////////
// Functions for communicating with MIFARE PICCs
/////////////////////////////////////////////////////////////////////////////////////
StatusCode PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);
void PCD_StopCrypto1();
StatusCode MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize);
StatusCode MIFARE_Write(byte blockAddr, byte *buffer, byte bufferSize);
StatusCode MIFARE_Ultralight_Write(byte page, byte *buffer, byte bufferSize);
StatusCode MIFARE_Decrement(byte blockAddr, int32_t delta);
StatusCode MIFARE_Increment(byte blockAddr, int32_t delta);
StatusCode MIFARE_Restore(byte blockAddr);
StatusCode MIFARE_Transfer(byte blockAddr);
StatusCode MIFARE_GetValue(byte blockAddr, int32_t *value);
StatusCode MIFARE_SetValue(byte blockAddr, int32_t value);
StatusCode PCD_NTAG216_AUTH(byte *passWord, byte pACK[]);
/////////////////////////////////////////////////////////////////////////////////////
// Support functions
/////////////////////////////////////////////////////////////////////////////////////
StatusCode PCD_MIFARE_Transceive(byte *sendData, byte sendLen, bool acceptTimeout);
// old function used too much memory, now name moved to flash; if you need char, copy from flash to memory
//const char *GetStatusCodeName(byte code);
const char *GetStatusCodeName(StatusCode code);
PICC_Type PICC_GetType(byte sak);
// old function used too much memory, now name moved to flash; if you need char, copy from flash to memory
//const char *PICC_GetTypeName(byte type);
const char *PICC_GetTypeName(PICC_Type type);
// Support functions for debuging
void PCD_DumpVersionToSerial();
void PICC_DumpToSerial(Uid *uid);
void PICC_DumpDetailsToSerial(Uid *uid);
void PICC_DumpMifareClassicToSerial(Uid *uid, PICC_Type piccType, MIFARE_Key *key);
void PICC_DumpMifareClassicSectorToSerial(Uid *uid, MIFARE_Key *key, byte sector);
void PICC_DumpMifareUltralightToSerial();
// Advanced functions for MIFARE
void MIFARE_SetAccessBits(byte *accessBitBuffer, byte g0, byte g1, byte g2, byte g3);
bool MIFARE_OpenUidBackdoor(bool logErrors);
bool MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors);
bool MIFARE_UnbrickUidSector(bool logErrors);
/////////////////////////////////////////////////////////////////////////////////////
// Convenience functions - does not add extra functionality
/////////////////////////////////////////////////////////////////////////////////////
bool PICC_IsNewCardPresent();
bool PICC_ReadCardSerial();
//byte _chipSelectPin; // Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
//byte _resetPowerDownPin; // Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
StatusCode MIFARE_TwoStepHelper(byte command, byte blockAddr, int32_t data);
void initRc522();
#endif /* MAIN_RC522_H_ */

0
components/auth/include/wiegand.h Normal file → Executable file
View File

107
components/auth/src/auth.c Normal file → Executable file
View File

@@ -1,11 +1,108 @@
#include "auth.h"
#include "wiegand_reader.h"
#include "wiegand_handler.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_log.h>
#include <string.h>
static bool enable = false;
#define MAX_TAGS 50
#define TAG_LEN 20
void auth_set_enable(bool value) {
enable = value;
static const char *TAG = "Auth";
static bool enabled = true;
static char valid_tags[MAX_TAGS][TAG_LEN];
static int tag_count = 0;
static bool is_tag_valid(const char *tag) {
for (int i = 0; i < tag_count; i++) {
if (strncmp(valid_tags[i], tag, TAG_LEN) == 0) {
return true;
}
}
return false;
}
bool auth_get_enable(void) {
return enable;
void auth_set_enabled(bool value) {
enabled = value;
ESP_LOGI(TAG, "Wiegand reader %s", enabled ? "ENABLED" : "DISABLED");
}
bool auth_is_enabled(void) {
return enabled;
}
bool auth_add_tag(const char *tag) {
if (tag_count >= MAX_TAGS) return false;
if (auth_tag_exists(tag)) return true;
strncpy(valid_tags[tag_count], tag, TAG_LEN - 1);
valid_tags[tag_count][TAG_LEN - 1] = '\0';
tag_count++;
ESP_LOGI(TAG, "Tag added: %s", tag);
return true;
}
bool auth_remove_tag(const char *tag) {
for (int i = 0; i < tag_count; i++) {
if (strncmp(valid_tags[i], tag, TAG_LEN) == 0) {
for (int j = i; j < tag_count - 1; j++) {
strncpy(valid_tags[j], valid_tags[j + 1], TAG_LEN);
}
tag_count--;
ESP_LOGI(TAG, "Tag removed: %s", tag);
return true;
}
}
return false;
}
bool auth_tag_exists(const char *tag) {
return is_tag_valid(tag);
}
void auth_list_tags(void) {
ESP_LOGI(TAG, "Registered Tags (%d):", tag_count);
for (int i = 0; i < tag_count; i++) {
ESP_LOGI(TAG, "- %s", valid_tags[i]);
}
}
// Função de callback para o reader
static void on_card_read(const wiegand_packet_t *packet) {
if (!enabled) {
ESP_LOGW(TAG, "Ignoring Wiegand data: reader is disabled");
return;
}
char tag[TAG_LEN];
memset(tag, 0, TAG_LEN);
if (packet->bits == 26) {
snprintf(tag, TAG_LEN, "%03d%03d%03d", packet->data[0], packet->data[1], packet->data[2]);
} else if (packet->bits == 34) {
snprintf(tag, TAG_LEN, "%03d%03d%03d%03d", packet->data[0], packet->data[1], packet->data[2], packet->data[3]);
} else {
ESP_LOGW(TAG, "Unsupported bit length: %d", packet->bits);
return;
}
ESP_LOGI(TAG, "Tag read: %s", tag);
if (is_tag_valid(tag)) {
ESP_LOGI(TAG, "Authorized tag.");
evse_authorize();
if (ocpp_is_TransactionActive()) {
ocpp_end_transaction(tag);
} else {
ocpp_begin_transaction(tag);
}
} else {
ESP_LOGW(TAG, "Unauthorized tag.");
}
}
void auth_init(void) {
wiegand_reader_init(19, 18, on_card_read);
}

File diff suppressed because it is too large Load Diff

112
components/auth/src/wiegand.c Normal file → Executable file
View File

@@ -1,112 +1,18 @@
#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <wiegand.h>
#include "wiegand_reader.h"
#include "wiegand.h"
#include <esp_log.h>
#include <string.h>
#include <evse_api.h>
#include <ocpp.h>
#include <freertos/FreeRTOS.h>
static const char *TAG = "Wiegand_reader";
#define WIEGAND_PIN_D0 19
#define WIEGAND_PIN_D1 18
#define WIEGAND_BUF_SIZE 50
#define QUEUE_SIZE 10
static const char *TAG = "WiegandReader";
static wiegand_reader_t reader;
static QueueHandle_t data_queue = NULL;
// Single data packet
typedef struct
void wiegand_reader_init(int pin_d0, int pin_d1, wiegand_callback_t callback)
{
uint8_t data[WIEGAND_BUF_SIZE];
size_t bits;
} data_packet_t;
// callback on new data in reader
static void reader_callback(wiegand_reader_t *r)
{
data_packet_t p;
p.bits = r->bits;
size_t data_size = (r->bits + 7) / 8;
memcpy(p.data, r->buf, data_size);
if (xQueueSendToBack(data_queue, &p, portMAX_DELAY) != pdTRUE) {
ESP_LOGE(TAG, "Failed to send data to queue");
}
}
static void wiegand_task(void *arg)
{
// Create queue
data_queue = xQueueCreate(QUEUE_SIZE, sizeof(data_packet_t));
if (!data_queue)
{
ESP_LOGE(TAG, "Error creating queue");
ESP_ERROR_CHECK(ESP_ERR_NO_MEM);
}
// Initialize reader
esp_err_t err = wiegand_reader_init(&reader, WIEGAND_PIN_D0, WIEGAND_PIN_D1,
true, WIEGAND_BUF_SIZE, reader_callback,
WIEGAND_MSB_FIRST, WIEGAND_LSB_FIRST);
esp_err_t err = wiegand_reader_config(&reader, pin_d0, pin_d1,
callback,
WIEGAND_MSB_FIRST, WIEGAND_LSB_FIRST);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize Wiegand reader: %s", esp_err_to_name(err));
return;
}
data_packet_t p;
while (1)
{
ESP_LOGI(TAG, "Waiting for Wiegand data...");
if (xQueueReceive(data_queue, &p, pdMS_TO_TICKS(1000)) != pdTRUE) {
ESP_LOGW(TAG, "No Wiegand data received within the timeout");
continue;
}
ESP_LOGI(TAG, "Bits received: %d", p.bits);
for (size_t i = 0; i < (p.bits + 7) / 8; i++)
ESP_LOGI(TAG, " 0x%02x", p.data[i]);
char str[20];
if (p.bits == 26 || p.bits == 34)
{
evse_authorize();
/*----26
sprintf(str, "%03d%03d%03d", p.data[0], p.data[1], p.data[2]);
if (ocpp_is_TransactionActive())
{
ocpp_end_transaction(str);
}
else
{
ocpp_begin_transaction(str);
}*/
/*----34
sprintf(str, "%03d%03d%03d%03d", p.data[0], p.data[1], p.data[2], p.data[3]);
if (ocpp_is_TransactionActive())
{
ocpp_end_transaction(str);
}
else
{
ocpp_begin_transaction(str);
}
*/
}
ESP_LOGE(TAG, "Failed to init Wiegand reader: %s", esp_err_to_name(err));
}
}
void initialize_wiegand_reader()
{
ESP_LOGI(TAG, "Starting Wiegand reader");
xTaskCreate(wiegand_task, TAG, configMINIMAL_STACK_SIZE * 4, NULL, 5, NULL);
}

View File

@@ -1,3 +1,5 @@
#include <inttypes.h> // Include for PRI macros
#include "evse_config.h"
#include "board_config.h"
#include "evse_limits.h"
@@ -8,7 +10,7 @@ static const char *TAG = "evse_config";
static nvs_handle_t nvs;
// Parâmetros configuráveis
// Configurable parameters
static uint8_t max_charging_current = MAX_CHARGING_CURRENT_LIMIT;
static uint8_t grid_max_current = MAX_GRID_CURRENT_LIMIT;
static uint16_t charging_current;
@@ -18,7 +20,8 @@ static uint8_t temp_threshold = 60;
static bool require_auth;
esp_err_t evse_config_init(void) {
ESP_LOGI(TAG, "Abrindo namespace NVS");
ESP_LOGD(TAG, "Initializing NVS configuration...");
ESP_LOGI(TAG, "Opening NVS namespace");
return nvs_open("evse", NVS_READWRITE, &nvs);
}
@@ -29,32 +32,40 @@ void evse_check_defaults(void) {
uint32_t u32;
bool needs_commit = false;
ESP_LOGD(TAG, "Checking default parameters...");
// Max charging current
err = nvs_get_u8(nvs, "max_chrg_curr", &u8);
ESP_LOGD(TAG, "Max charging current read: %d", u8);
if (err != ESP_OK || u8 < MIN_CHARGING_CURRENT_LIMIT || u8 > MAX_CHARGING_CURRENT_LIMIT) {
max_charging_current = MAX_CHARGING_CURRENT_LIMIT;
nvs_set_u8(nvs, "max_chrg_curr", max_charging_current);
needs_commit = true;
ESP_LOGD(TAG, "Max charging current adjusted to: %d", max_charging_current);
} else {
max_charging_current = u8;
}
// Grid max current
err = nvs_get_u8(nvs, "grid_max_curr", &u8);
ESP_LOGD(TAG, "Grid max current read: %d", u8);
if (err != ESP_OK || u8 < MIN_GRID_CURRENT_LIMIT || u8 > MAX_GRID_CURRENT_LIMIT) {
grid_max_current = MAX_GRID_CURRENT_LIMIT;
nvs_set_u8(nvs, "grid_max_curr", grid_max_current);
needs_commit = true;
ESP_LOGD(TAG, "Grid max current adjusted to: %d", grid_max_current);
} else {
grid_max_current = u8;
}
// Charging current (decA)
err = nvs_get_u16(nvs, "def_chrg_curr", &u16);
ESP_LOGD(TAG, "Charging current read: %d", u16);
if (err != ESP_OK || u16 < (MIN_CHARGING_CURRENT_LIMIT * 10) || u16 > (max_charging_current * 10)) {
charging_current = max_charging_current * 10;
nvs_set_u16(nvs, "def_chrg_curr", charging_current);
needs_commit = true;
ESP_LOGD(TAG, "Charging current adjusted to: %d", charging_current);
} else {
charging_current = u16;
}
@@ -64,6 +75,7 @@ void evse_check_defaults(void) {
if (err != ESP_OK) {
nvs_set_u8(nvs, "require_auth", require_auth);
needs_commit = true;
ESP_LOGD(TAG, "Require auth adjusted to: %d", require_auth);
}
err = nvs_get_u8(nvs, "socket_outlet", &u8);
@@ -71,6 +83,7 @@ void evse_check_defaults(void) {
if (err != ESP_OK) {
nvs_set_u8(nvs, "socket_outlet", socket_outlet);
needs_commit = true;
ESP_LOGD(TAG, "Socket outlet adjusted to: %d", socket_outlet);
}
err = nvs_get_u8(nvs, "rcm", &u8);
@@ -78,6 +91,7 @@ void evse_check_defaults(void) {
if (err != ESP_OK) {
nvs_set_u8(nvs, "rcm", rcm);
needs_commit = true;
ESP_LOGD(TAG, "RCM adjusted to: %d", rcm);
}
err = nvs_get_u8(nvs, "temp_threshold", &u8);
@@ -85,119 +99,181 @@ void evse_check_defaults(void) {
if (err != ESP_OK) {
nvs_set_u8(nvs, "temp_threshold", temp_threshold);
needs_commit = true;
ESP_LOGD(TAG, "Temp threshold adjusted to: %d", temp_threshold);
}
// Limites adicionais
// Additional limits
if (nvs_get_u32(nvs, "def_cons_lim", &u32) == ESP_OK) {
evse_set_consumption_limit(u32);
ESP_LOGD(TAG, "Consumption limit read and applied: %" PRIu32, u32); // Updated to PRIu32
}
if (nvs_get_u32(nvs, "def_ch_time_lim", &u32) == ESP_OK) {
evse_set_charging_time_limit(u32);
ESP_LOGD(TAG, "Charging time limit read and applied: %" PRIu32, u32); // Updated to PRIu32
}
if (nvs_get_u16(nvs, "def_un_pwr_lim", &u16) == ESP_OK) {
evse_set_under_power_limit(u16);
ESP_LOGD(TAG, "Under power limit read and applied: %d", u16);
}
if (needs_commit) {
nvs_commit(nvs);
ESP_LOGD(TAG, "Changes committed to NVS.");
}
}
// Corrente
uint8_t evse_get_max_charging_current(void) { return max_charging_current; }
// Current
uint8_t evse_get_max_charging_current(void) {
ESP_LOGI(TAG, "Max charging current read: %d", max_charging_current);
return max_charging_current;
}
esp_err_t evse_set_max_charging_current(uint8_t value) {
ESP_LOGI(TAG, "Attempting to set max charging current: %d", value);
if (value < MIN_CHARGING_CURRENT_LIMIT || value > MAX_CHARGING_CURRENT_LIMIT)
return ESP_ERR_INVALID_ARG;
max_charging_current = value;
nvs_set_u8(nvs, "max_chrg_curr", value);
return nvs_commit(nvs);
nvs_commit(nvs);
ESP_LOGD(TAG, "Max charging current adjusted to: %d", max_charging_current);
return ESP_OK;
}
uint8_t grid_get_max_current(void) {
ESP_LOGD(TAG, "Grid max current read: %d", grid_max_current);
return grid_max_current;
}
uint8_t grid_get_max_current(void) { return grid_max_current; }
esp_err_t grid_set_max_current(uint8_t value) {
ESP_LOGD(TAG, "Attempting to set grid max current: %d", value);
if (value < MIN_GRID_CURRENT_LIMIT || value > MAX_GRID_CURRENT_LIMIT)
return ESP_ERR_INVALID_ARG;
grid_max_current = value;
nvs_set_u8(nvs, "grid_max_curr", value);
return nvs_commit(nvs);
nvs_commit(nvs);
ESP_LOGD(TAG, "Grid max current adjusted to: %d", grid_max_current);
return ESP_OK;
}
uint16_t evse_get_charging_current(void) {
ESP_LOGD(TAG, "Charging current read: %d", charging_current);
return charging_current;
}
uint16_t evse_get_charging_current(void) { return charging_current; }
esp_err_t evse_set_charging_current(uint16_t value) {
ESP_LOGD(TAG, "Attempting to set charging current: %d", value);
if (value < (MIN_CHARGING_CURRENT_LIMIT * 10) || value > (max_charging_current * 10))
return ESP_ERR_INVALID_ARG;
charging_current = value;
nvs_set_u16(nvs, "def_chrg_curr", value);
return nvs_commit(nvs);
nvs_commit(nvs);
ESP_LOGD(TAG, "Charging current adjusted to: %d", charging_current);
return ESP_OK;
}
uint16_t evse_get_default_charging_current(void) {
uint16_t value;
nvs_get_u16(nvs, "def_chrg_curr", &value);
ESP_LOGD(TAG, "Default charging current read: %d", value);
return value;
}
esp_err_t evse_set_default_charging_current(uint16_t value) {
ESP_LOGD(TAG, "Attempting to set default charging current: %d", value);
if (value < (MIN_CHARGING_CURRENT_LIMIT * 10) || value > (max_charging_current * 10))
return ESP_ERR_INVALID_ARG;
nvs_set_u16(nvs, "def_chrg_curr", value);
return nvs_commit(nvs);
nvs_commit(nvs);
ESP_LOGD(TAG, "Default charging current adjusted to: %d", value);
return ESP_OK;
}
// Socket outlet
bool evse_get_socket_outlet(void) { return socket_outlet; }
bool evse_get_socket_outlet(void) {
ESP_LOGD(TAG, "Socket outlet read: %d", socket_outlet);
return socket_outlet;
}
esp_err_t evse_set_socket_outlet(bool value) {
ESP_LOGD(TAG, "Attempting to set socket outlet: %d", value);
if (value && !board_config.proximity) return ESP_ERR_INVALID_ARG;
socket_outlet = value;
nvs_set_u8(nvs, "socket_outlet", value);
return nvs_commit(nvs);
nvs_commit(nvs);
ESP_LOGD(TAG, "Socket outlet adjusted to: %d", socket_outlet);
return ESP_OK;
}
// RCM
bool evse_is_rcm(void) { return rcm; }
bool evse_is_rcm(void) {
ESP_LOGD(TAG, "RCM read: %d", rcm);
return rcm;
}
esp_err_t evse_set_rcm(bool value) {
ESP_LOGD(TAG, "Attempting to set RCM: %d", value);
if (value && !board_config.rcm) return ESP_ERR_INVALID_ARG;
rcm = value;
nvs_set_u8(nvs, "rcm", value);
return nvs_commit(nvs);
nvs_commit(nvs);
ESP_LOGD(TAG, "RCM adjusted to: %d", rcm);
return ESP_OK;
}
// Temperature
uint8_t evse_get_temp_threshold(void) {
ESP_LOGD(TAG, "Temp threshold read: %d", temp_threshold);
return temp_threshold;
}
// Temperatura
uint8_t evse_get_temp_threshold(void) { return temp_threshold; }
esp_err_t evse_set_temp_threshold(uint8_t value) {
ESP_LOGI(TAG, "Attempting to set temp threshold: %d", value);
if (value < 40 || value > 80) return ESP_ERR_INVALID_ARG;
temp_threshold = value;
nvs_set_u8(nvs, "temp_threshold", value);
return nvs_commit(nvs);
nvs_commit(nvs);
ESP_LOGI(TAG, "Temp threshold adjusted to: %d", temp_threshold);
return ESP_OK;
}
// Authentication
bool evse_is_require_auth(void) {
ESP_LOGD(TAG, "Require auth read: %d", require_auth);
return require_auth;
}
// Autenticação
bool evse_is_require_auth(void) { return require_auth; }
void evse_set_require_auth(bool value) {
ESP_LOGI(TAG, "Attempting to set require auth: %d", value);
require_auth = value;
nvs_set_u8(nvs, "require_auth", value);
nvs_commit(nvs);
ESP_LOGI(TAG, "Require auth adjusted to: %d", require_auth);
}
// Disponibilidade
// Availability
static bool is_available = true;
bool evse_config_is_available(void) {
ESP_LOGD(TAG, "Checking availability: %d", is_available);
return is_available;
}
void evse_config_set_available(bool available) {
ESP_LOGD(TAG, "Setting availability to: %d", available);
is_available = available;
}
// Ativação/desativação
// Enable/Disable
static bool is_enabled = true;
bool evse_config_is_enabled(void) {
ESP_LOGD(TAG, "Checking if enabled: %d", is_enabled);
return is_enabled;
}
void evse_config_set_enabled(bool enabled) {
ESP_LOGD(TAG, "Setting enabled state to: %d", enabled);
is_enabled = enabled;
}

View File

@@ -15,7 +15,7 @@ extern "C" {
// Corrente máxima de carregamento (configurável pelo usuário)
#define MIN_CHARGING_CURRENT_LIMIT 6 // A
#define MAX_CHARGING_CURRENT_LIMIT 16 // A
#define MAX_CHARGING_CURRENT_LIMIT 32 // A
// Corrente máxima da rede elétrica (grid)
#define MIN_GRID_CURRENT_LIMIT 6 // A

View File

@@ -15,6 +15,8 @@
#include "esp_vfs.h"
#include "cJSON.h"
#include "rest.h"
#include "evse_api.h"
static const char *REST_TAG = "esp-rest";
#define REST_CHECK(a, str, goto_tag, ...) \
@@ -68,7 +70,7 @@ static struct {
int energyLimit;
int chargingTimeLimit;
int temperatureLimit;
} settings_config = {32, 0, 0, 0, 60};
} settings_config = {0, 0, 0, 0, 0};
// Estruturas para armazenar as configurações de autenticação e usuários
@@ -76,7 +78,7 @@ static struct {
bool RFID;
bool App;
bool Password;
} auth_methods = {false, false, true};
} auth_methods = {false, false, false};
static struct {
char username[128];
@@ -356,7 +358,9 @@ static esp_err_t config_settings_post_handler(httpd_req_t *req)
// Atualizando as configurações
cJSON *currentLimit = cJSON_GetObjectItem(json, "currentLimit");
if (currentLimit) settings_config.currentLimit = currentLimit->valueint;
if (currentLimit)
evse_set_max_charging_current(currentLimit->valueint);
//settings_config.currentLimit = currentLimit->valueint;
cJSON *powerLimit = cJSON_GetObjectItem(json, "powerLimit");
if (powerLimit) settings_config.powerLimit = powerLimit->valueint;
@@ -368,7 +372,10 @@ static esp_err_t config_settings_post_handler(httpd_req_t *req)
if (chargingTimeLimit) settings_config.chargingTimeLimit = chargingTimeLimit->valueint;
cJSON *temperatureLimit = cJSON_GetObjectItem(json, "temperatureLimit");
if (temperatureLimit) settings_config.temperatureLimit = temperatureLimit->valueint;
if (temperatureLimit)
evse_set_temp_threshold(temperatureLimit->valueint);
//settings_config.temperatureLimit = temperatureLimit->valueint;
cJSON_Delete(json);
@@ -386,11 +393,14 @@ static esp_err_t config_settings_get_handler(httpd_req_t *req)
// Criar objeto JSON para enviar as configurações atuais
cJSON *config = cJSON_CreateObject();
cJSON_AddNumberToObject(config, "currentLimit", settings_config.currentLimit);
cJSON_AddNumberToObject(config, "maxCurrentLimit", evse_get_max_charging_current());
cJSON_AddNumberToObject(config, "currentLimit", evse_get_max_charging_current());
cJSON_AddNumberToObject(config, "powerLimit", settings_config.powerLimit);
cJSON_AddNumberToObject(config, "energyLimit", settings_config.energyLimit);
cJSON_AddNumberToObject(config, "chargingTimeLimit", settings_config.chargingTimeLimit);
cJSON_AddNumberToObject(config, "temperatureLimit", settings_config.temperatureLimit);
cJSON_AddNumberToObject(config, "temperatureLimit", evse_get_temp_threshold());
// Convertendo para string e enviando a resposta
const char *config_str = cJSON_Print(config);
@@ -583,7 +593,7 @@ static esp_err_t config_auth_methods_get_handler(httpd_req_t *req)
// Criar objeto JSON com as configurações de métodos de autenticação
cJSON *config = cJSON_CreateObject();
cJSON_AddBoolToObject(config, "RFID", auth_methods.RFID);
cJSON_AddBoolToObject(config, "RFID", evse_is_require_auth());
cJSON_AddBoolToObject(config, "App", auth_methods.App);
cJSON_AddBoolToObject(config, "Password", auth_methods.Password);
@@ -618,7 +628,7 @@ static esp_err_t config_auth_methods_post_handler(httpd_req_t *req)
// Atualizando as configurações de autenticação
cJSON *RFID = cJSON_GetObjectItem(json, "RFID");
if (RFID) auth_methods.RFID = RFID->valueint;
if (RFID) evse_set_require_auth(RFID->valueint != 0);
cJSON *App = cJSON_GetObjectItem(json, "App");
if (App) auth_methods.App = App->valueint;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

2
components/protocols/webfolder/index.html Normal file → Executable file
View File

@@ -13,7 +13,7 @@
}
</style>
<title>Vite + React</title>
<script type="module" crossorigin src="/assets/index-BgLd2h-i.js"></script>
<script type="module" crossorigin src="/assets/index-3W2ZKmTa.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Brq1-keN.css">
</head>
<body>