refact auth

This commit is contained in:
2025-06-08 10:06:28 +01:00
parent 71b6cb7878
commit 214cf1ee04
236 changed files with 466 additions and 251 deletions

View File

@@ -1,22 +1,32 @@
/*
* auth.c
*/
#include "auth.h"
#include "wiegand_reader.h"
#include "wiegand_handler.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <esp_log.h>
#include <string.h>
#include "wiegand_reader.h" // necessário para initWiegand()
#define MAX_TAGS 50
#define TAG_LEN 20
static const char *TAG = "Auth";
static bool enabled = true;
static char valid_tags[MAX_TAGS][TAG_LEN];
static char valid_tags[MAX_TAGS][AUTH_TAG_MAX_LEN];
static int tag_count = 0;
// Fila para enviar eventos de autenticação
static QueueHandle_t event_queue = NULL;
void auth_set_event_queue(QueueHandle_t queue) {
event_queue = queue;
}
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) {
if (strncmp(valid_tags[i], tag, AUTH_TAG_MAX_LEN) == 0) {
return true;
}
}
@@ -25,7 +35,7 @@ static bool is_tag_valid(const char *tag) {
void auth_set_enabled(bool value) {
enabled = value;
ESP_LOGI(TAG, "Wiegand reader %s", enabled ? "ENABLED" : "DISABLED");
ESP_LOGI(TAG, "Auth %s", enabled ? "ENABLED" : "DISABLED");
}
bool auth_is_enabled(void) {
@@ -34,10 +44,11 @@ bool auth_is_enabled(void) {
bool auth_add_tag(const char *tag) {
if (tag_count >= MAX_TAGS) return false;
if (auth_tag_exists(tag)) return true;
if (!tag || strlen(tag) >= AUTH_TAG_MAX_LEN) return false;
if (is_tag_valid(tag)) return true;
strncpy(valid_tags[tag_count], tag, TAG_LEN - 1);
valid_tags[tag_count][TAG_LEN - 1] = '\0';
strncpy(valid_tags[tag_count], tag, AUTH_TAG_MAX_LEN - 1);
valid_tags[tag_count][AUTH_TAG_MAX_LEN - 1] = '\0';
tag_count++;
ESP_LOGI(TAG, "Tag added: %s", tag);
return true;
@@ -45,9 +56,9 @@ bool auth_add_tag(const char *tag) {
bool auth_remove_tag(const char *tag) {
for (int i = 0; i < tag_count; i++) {
if (strncmp(valid_tags[i], tag, TAG_LEN) == 0) {
if (strncmp(valid_tags[i], tag, AUTH_TAG_MAX_LEN) == 0) {
for (int j = i; j < tag_count - 1; j++) {
strncpy(valid_tags[j], valid_tags[j + 1], TAG_LEN);
strncpy(valid_tags[j], valid_tags[j + 1], AUTH_TAG_MAX_LEN);
}
tag_count--;
ESP_LOGI(TAG, "Tag removed: %s", tag);
@@ -68,41 +79,29 @@ void auth_list_tags(void) {
}
}
// 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");
void auth_init(void) {
auth_set_enabled(true); // Default: enabled
initWiegand(); // Inicializa automaticamente o leitor Wiegand 26
}
void auth_process_tag(const char *tag) {
if (!tag || !auth_is_enabled()) {
ESP_LOGW(TAG, "Auth disabled or NULL tag received.");
return;
}
char tag[TAG_LEN];
memset(tag, 0, TAG_LEN);
auth_event_t event;
strncpy(event.tag, tag, AUTH_TAG_MAX_LEN - 1);
event.tag[AUTH_TAG_MAX_LEN - 1] = '\0';
event.authorized = is_tag_valid(tag);
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 %s: %s", tag, event.authorized ? "AUTHORIZED" : "DENIED");
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);
if (event_queue) {
if (xQueueSend(event_queue, &event, pdMS_TO_TICKS(100)) != pdPASS) {
ESP_LOGW(TAG, "Auth event queue full, dropping tag: %s", tag);
}
} else {
ESP_LOGW(TAG, "Unauthorized tag.");
ESP_LOGW(TAG, "Auth event queue not set");
}
}
void auth_init(void) {
wiegand_reader_init(19, 18, on_card_read);
}

View File

@@ -1,18 +1,181 @@
#include "wiegand_reader.h"
#include "wiegand.h"
/**
* @file wiegand.c
*
* ESP-IDF Wiegand protocol receiver
*/
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <string.h>
#include <stdlib.h>
#include <esp_idf_lib_helpers.h>
#include "wiegand.h"
static const char *TAG = "WiegandReader";
static const char *TAG = "wiegand";
static wiegand_reader_t reader;
#define TIMER_INTERVAL_US 50000 // 50ms
void wiegand_reader_init(int pin_d0, int pin_d1, wiegand_callback_t callback)
#define CHECK(x) \
do \
{ \
esp_err_t __; \
if ((__ = x) != ESP_OK) \
return __; \
} while (0)
#define CHECK_ARG(VAL) \
do \
{ \
if (!(VAL)) \
return ESP_ERR_INVALID_ARG; \
} while (0)
static void isr_disable(wiegand_reader_t *reader)
{
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 init Wiegand reader: %s", esp_err_to_name(err));
}
gpio_set_intr_type(reader->gpio_d0, GPIO_INTR_DISABLE);
gpio_set_intr_type(reader->gpio_d1, GPIO_INTR_DISABLE);
}
static void isr_enable(wiegand_reader_t *reader)
{
gpio_set_intr_type(reader->gpio_d0, GPIO_INTR_NEGEDGE);
gpio_set_intr_type(reader->gpio_d1, GPIO_INTR_NEGEDGE);
}
#if HELPER_TARGET_IS_ESP32
static void IRAM_ATTR isr_handler(void *arg)
#else
static void isr_handler(void *arg)
#endif
{
wiegand_reader_t *reader = (wiegand_reader_t *)arg;
if (!reader->enabled)
return;
int d0 = gpio_get_level(reader->gpio_d0);
int d1 = gpio_get_level(reader->gpio_d1);
// ignore equal
if (d0 == d1)
return;
// overflow
if (reader->bits >= reader->size * 8)
return;
esp_timer_stop(reader->timer);
uint8_t value;
if (reader->bit_order == WIEGAND_MSB_FIRST)
value = (d0 ? 0x80 : 0) >> (reader->bits % 8);
else
value = (d0 ? 1 : 0) << (reader->bits % 8);
if (reader->byte_order == WIEGAND_MSB_FIRST)
reader->buf[reader->size - reader->bits / 8 - 1] |= value;
else
reader->buf[reader->bits / 8] |= value;
reader->bits++;
esp_timer_start_once(reader->timer, TIMER_INTERVAL_US);
}
static void timer_handler(void *arg)
{
wiegand_reader_t *reader = (wiegand_reader_t *)arg;
ESP_LOGI(TAG, "Got %d bits of data", reader->bits);
wiegand_reader_disable(reader);
if (reader->callback)
reader->callback(reader);
wiegand_reader_enable(reader);
isr_enable(reader);
}
////////////////////////////////////////////////////////////////////////////////
esp_err_t wiegand_reader_init(wiegand_reader_t *reader, gpio_num_t gpio_d0, gpio_num_t gpio_d1,
bool internal_pullups, size_t buf_size, wiegand_callback_t callback, wiegand_order_t bit_order,
wiegand_order_t byte_order)
{
CHECK_ARG(reader && buf_size && callback);
esp_err_t res = gpio_install_isr_service(0);
if (res != ESP_OK && res != ESP_ERR_INVALID_STATE)
return res;
memset(reader, 0, sizeof(wiegand_reader_t));
reader->gpio_d0 = gpio_d0;
reader->gpio_d1 = gpio_d1;
reader->size = buf_size;
reader->buf = calloc(buf_size, 1);
reader->bit_order = bit_order;
reader->byte_order = byte_order;
reader->callback = callback;
esp_timer_create_args_t timer_args = {
.name = TAG,
.arg = reader,
.callback = timer_handler,
.dispatch_method = ESP_TIMER_TASK};
CHECK(esp_timer_create(&timer_args, &reader->timer));
CHECK(gpio_set_direction(gpio_d0, GPIO_MODE_INPUT));
CHECK(gpio_set_direction(gpio_d1, GPIO_MODE_INPUT));
CHECK(gpio_set_pull_mode(gpio_d0, internal_pullups ? GPIO_PULLUP_ONLY : GPIO_FLOATING));
CHECK(gpio_set_pull_mode(gpio_d1, internal_pullups ? GPIO_PULLUP_ONLY : GPIO_FLOATING));
isr_disable(reader);
CHECK(gpio_isr_handler_add(gpio_d0, isr_handler, reader));
CHECK(gpio_isr_handler_add(gpio_d1, isr_handler, reader));
isr_enable(reader);
reader->enabled = true;
ESP_LOGI(TAG, "Reader initialized on D0=%d, D1=%d", gpio_d0, gpio_d1);
return ESP_OK;
}
esp_err_t wiegand_reader_disable(wiegand_reader_t *reader)
{
CHECK_ARG(reader);
isr_disable(reader);
esp_timer_stop(reader->timer);
reader->enabled = false;
ESP_LOGI(TAG, "Reader on D0=%d, D1=%d disabled", reader->gpio_d0, reader->gpio_d1);
return ESP_OK;
}
esp_err_t wiegand_reader_enable(wiegand_reader_t *reader)
{
CHECK_ARG(reader);
reader->bits = 0;
memset(reader->buf, 0, reader->size);
isr_enable(reader);
reader->enabled = true;
ESP_LOGI(TAG, "Reader on D0=%d, D1=%d enabled", reader->gpio_d0, reader->gpio_d1);
return ESP_OK;
}
esp_err_t wiegand_reader_done(wiegand_reader_t *reader)
{
CHECK_ARG(reader && reader->buf);
isr_disable(reader);
CHECK(gpio_isr_handler_remove(reader->gpio_d0));
CHECK(gpio_isr_handler_remove(reader->gpio_d1));
esp_timer_stop(reader->timer);
CHECK(esp_timer_delete(reader->timer));
free(reader->buf);
ESP_LOGI(TAG, "Reader removed");
return ESP_OK;
}

View File

@@ -1,138 +1,90 @@
/*
* wiegand.c
*
* Created on:
* Author:
* wiegand_reader.c
*/
#include <stdio.h>
#include <string.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <wiegand.h>
#include <esp_log.h>
#include <string.h>
#include <wiegand.h>
#include <evse_api.h>
#include <ocpp.h>
#include "auth.h"
static const char *TAG = "Wiegand_reader";
#define CONFIG_EXAMPLE_BUF_SIZE 50
static const char *TAG = "WiegandReader";
static wiegand_reader_t reader;
static QueueHandle_t queue = NULL;
#define CONFIG_EXAMPLE_BUF_SIZE 50
// Single data packet
typedef struct
{
typedef struct {
uint8_t data[CONFIG_EXAMPLE_BUF_SIZE];
size_t bits;
} data_packet_t;
// callback on new data in reader
static void reader_callback(wiegand_reader_t *r)
{
// you can decode raw data from reader buffer here, but remember:
// reader will ignore any new incoming data while executing callback
// create simple undecoded data packet
static void reader_callback(wiegand_reader_t *r) {
data_packet_t p;
p.bits = r->bits;
memcpy(p.data, r->buf, CONFIG_EXAMPLE_BUF_SIZE);
// Send it to the queue
xQueueSendToBack(queue, &p, 0);
}
static void wiegand_task(void *arg)
{
// Create queue
static void wiegand_task(void *arg) {
queue = xQueueCreate(5, sizeof(data_packet_t));
if (!queue)
{
ESP_LOGE(TAG, "Error creating queue");
ESP_ERROR_CHECK(ESP_ERR_NO_MEM);
if (!queue) {
ESP_LOGE(TAG, "Failed to create queue");
vTaskDelete(NULL);
return;
}
// Initialize reader
ESP_ERROR_CHECK(wiegand_reader_init(&reader, 19, 18,
true, CONFIG_EXAMPLE_BUF_SIZE, reader_callback, WIEGAND_MSB_FIRST, WIEGAND_LSB_FIRST));
true, CONFIG_EXAMPLE_BUF_SIZE, reader_callback, WIEGAND_MSB_FIRST, WIEGAND_LSB_FIRST));
data_packet_t p;
while (1)
{
while (1) {
ESP_LOGI(TAG, "Waiting for Wiegand data...");
xQueueReceive(queue, &p, portMAX_DELAY);
if (xQueueReceive(queue, &p, portMAX_DELAY) == pdPASS) {
ESP_LOGI(TAG, "Bits received: %d", p.bits);
// dump received data
// ESP_LOGI(TAG, "==========================================");
ESP_LOGI(TAG, "Bits received: %d\n", p.bits);
ESP_LOGI(TAG, "Received data:");
int bytes = p.bits / 8;
int tail = p.bits % 8;
for (size_t i = 0; i < bytes + (tail ? 1 : 0); i++)
printf(" 0x%02x", p.data[i]);
char tag[20] = {0};
char str[20];
if (p.bits == 26)
{
evse_authorize();
/*
sprintf(str, "%03d%03d%03d", p.data[0], p.data[1], p.data[2]);
if (ocpp_is_TransactionActive())
{
ocpp_end_transaction(str);
if (p.bits == 26) {
snprintf(tag, sizeof(tag), "%03d%03d%03d", p.data[0], p.data[1], p.data[2]);
} else if (p.bits == 34) {
snprintf(tag, sizeof(tag), "%03d%03d%03d%03d", p.data[0], p.data[1], p.data[2], p.data[3]);
} else {
ESP_LOGW(TAG, "Unsupported bit length: %d", (int)p.bits);
continue;
}
else
{
ocpp_begin_transaction(str);
}*/
}
else if (p.bits == 34)
{
evse_authorize();
/*
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);
ESP_LOGI(TAG, "Tag read: %s", tag);
if (!auth_is_enabled()) {
ESP_LOGW(TAG, "Auth disabled, ignoring tag.");
continue;
}
else
{
ocpp_begin_transaction(str);
if (auth_tag_exists(tag)) {
ESP_LOGI(TAG, "Authorized tag. Proceeding...");
evse_authorize();
if (ocpp_is_TransactionActive()) {
ocpp_end_transaction(tag);
} else {
ocpp_begin_transaction(tag);
}
} else {
ESP_LOGW(TAG, "Unauthorized tag: %s", tag);
}
*/
}
}
// ESP_LOGI(TAG, "==========================================");
}
/*
static void wiegand_task(void *arg)
{
while (1)
{
vTaskDelay(pdMS_TO_TICKS(15000));
ocpp_begin_transaction("AAAAAA");
vTaskDelay(pdMS_TO_TICKS(15000));
ocpp_end_transaction("AAAAAA");
vTaskDelay(pdMS_TO_TICKS(15000));
ocpp_begin_transaction("AAAAAB");
vTaskDelay(pdMS_TO_TICKS(15000));
ocpp_end_transaction("AAAAAB");
}
}
*/
void initWiegand()
{
ESP_LOGI(TAG, "Starting wiegand");
// xTaskCreate(&wiegand_task, "wiegandtask", 8192, NULL, 5, NULL);
void initWiegand(void) {
ESP_LOGI(TAG, "Initializing Wiegand reader");
xTaskCreate(wiegand_task, TAG, configMINIMAL_STACK_SIZE * 4, NULL, 5, NULL);
}
}