code cleanup
Some checks failed
ESP-IDF Build / build (esp32c6, release-v5.4) (push) Has been cancelled
ESP-IDF Build / build (esp32c6, release-v5.5) (push) Has been cancelled
ESP-IDF Build / build (esp32s3, release-v5.4) (push) Has been cancelled
ESP-IDF Build / build (esp32s3, release-v5.5) (push) Has been cancelled
Some checks failed
ESP-IDF Build / build (esp32c6, release-v5.4) (push) Has been cancelled
ESP-IDF Build / build (esp32c6, release-v5.5) (push) Has been cancelled
ESP-IDF Build / build (esp32s3, release-v5.4) (push) Has been cancelled
ESP-IDF Build / build (esp32s3, release-v5.5) (push) Has been cancelled
Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
idf_component_register(SRCS
|
||||
src/ble/ble_connection.c
|
||||
src/ble/ble_scanner.c
|
||||
src/ble_manager.c
|
||||
src/wifi_manager.c
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_REQUIRES
|
||||
REQUIRES
|
||||
bt
|
||||
driver
|
||||
nvs_flash
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: '>=4.1.0'
|
||||
|
||||
espressif/ble_conn_mgr: '^0.1.3'
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "ble_device.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
void ble_connect(device_info_t *device);
|
||||
void ble_clear_bonds(void);
|
||||
void ble_clear_bond(const ble_addr_t *addr);
|
||||
void read_characteristic(uint16_t char_val_handle);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <host/ble_hs.h>
|
||||
#include <host/util/util.h>
|
||||
#include <nimble/nimble_port.h>
|
||||
#include <nimble/nimble_port_freertos.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Structure to cache device data
|
||||
typedef struct
|
||||
{
|
||||
ble_addr_t addr;
|
||||
uint16_t manufacturer_id;
|
||||
uint8_t manufacturer_data[31]; // Max. length of manufacturer data
|
||||
uint8_t manufacturer_data_len;
|
||||
char name[32];
|
||||
uint16_t service_uuids_16[10]; // Up to 10 16-bit Service UUIDs
|
||||
uint8_t service_uuids_16_count;
|
||||
ble_uuid128_t service_uuids_128[5]; // Up to 5 128-bit Service UUIDs
|
||||
uint8_t service_uuids_128_count;
|
||||
bool has_manufacturer;
|
||||
bool has_name;
|
||||
int8_t rssi;
|
||||
} device_info_t;
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "ble_device.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
void start_scan(void);
|
||||
int get_device_count(void);
|
||||
device_info_t *get_device(int index);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -5,6 +5,7 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
void ble_manager_task(void *pvParameter);
|
||||
void ble_connect_to_device(int index);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,364 @@
|
||||
#include "ble/ble_connection.h"
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <host/ble_gap.h>
|
||||
#include <host/ble_hs.h>
|
||||
#include <host/ble_sm.h>
|
||||
#include <host/ble_store.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *TAG = "ble_connection";
|
||||
|
||||
static uint16_t g_conn_handle;
|
||||
static uint16_t g_char_val_handle; // Handle der Characteristic, die du lesen willst
|
||||
static bool g_bonding_in_progress = false;
|
||||
|
||||
const char *ble_error_to_string(int status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case 0:
|
||||
return "Success";
|
||||
case BLE_HS_EDONE:
|
||||
return "Operation complete";
|
||||
case BLE_HS_EALREADY:
|
||||
return "Operation already in progress";
|
||||
case BLE_HS_EINVAL:
|
||||
return "Invalid argument";
|
||||
case BLE_HS_EMSGSIZE:
|
||||
return "Message too large";
|
||||
case BLE_HS_ENOENT:
|
||||
return "No entry found";
|
||||
case BLE_HS_ENOMEM:
|
||||
return "Out of memory";
|
||||
case BLE_HS_ENOTCONN:
|
||||
return "Not connected";
|
||||
case BLE_HS_ENOTSUP:
|
||||
return "Not supported";
|
||||
case BLE_HS_EAPP:
|
||||
return "Application error";
|
||||
case BLE_HS_EBADDATA:
|
||||
return "Bad data";
|
||||
case BLE_HS_EOS:
|
||||
return "OS error";
|
||||
case BLE_HS_ECONTROLLER:
|
||||
return "Controller error";
|
||||
case BLE_HS_ETIMEOUT:
|
||||
return "Timeout";
|
||||
case BLE_HS_EBUSY:
|
||||
return "Busy";
|
||||
case BLE_HS_EREJECT:
|
||||
return "Rejected";
|
||||
case BLE_HS_EUNKNOWN:
|
||||
return "Unknown error";
|
||||
case BLE_HS_EROLE:
|
||||
return "Role error";
|
||||
case BLE_HS_ETIMEOUT_HCI:
|
||||
return "HCI timeout";
|
||||
case BLE_HS_ENOMEM_EVT:
|
||||
return "No memory for event";
|
||||
case BLE_HS_ENOADDR:
|
||||
return "No address";
|
||||
case BLE_HS_ENOTSYNCED:
|
||||
return "Not synchronized";
|
||||
case BLE_HS_EAUTHEN:
|
||||
return "Authentication failed";
|
||||
case BLE_HS_EAUTHOR:
|
||||
return "Authorization failed";
|
||||
case BLE_HS_EENCRYPT:
|
||||
return "Encryption failed";
|
||||
case BLE_HS_EENCRYPT_KEY_SZ:
|
||||
return "Encryption key size";
|
||||
case BLE_HS_ESTORE_CAP:
|
||||
return "Storage capacity exceeded";
|
||||
case BLE_HS_ESTORE_FAIL:
|
||||
return "Storage failure";
|
||||
default:
|
||||
// ATT-Fehler prüfen
|
||||
if ((status & 0x100) == 0x100)
|
||||
{
|
||||
return "ATT error";
|
||||
}
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_sm_event_cb(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
switch (event->type)
|
||||
{
|
||||
case BLE_GAP_EVENT_PASSKEY_ACTION:
|
||||
ESP_LOGI(TAG, "Passkey action required");
|
||||
// Hier können Sie Passkey-Aktionen implementieren
|
||||
// z.B. Display passkey, Input passkey, etc.
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_ENC_CHANGE:
|
||||
ESP_LOGI(TAG, "Encryption change: status=%d", event->enc_change.status);
|
||||
if (event->enc_change.status == 0)
|
||||
{
|
||||
ESP_LOGI(TAG, "Encryption established successfully");
|
||||
g_bonding_in_progress = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_REPEAT_PAIRING:
|
||||
ESP_LOGI(TAG, "Repeat pairing");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_device_bonded(const ble_addr_t *addr)
|
||||
{
|
||||
struct ble_store_value_sec sec_value;
|
||||
struct ble_store_key_sec sec_key = {0};
|
||||
|
||||
sec_key.peer_addr = *addr;
|
||||
sec_key.idx = 0;
|
||||
|
||||
int rc = ble_store_read_peer_sec(&sec_key, &sec_value);
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
static void initiate_bonding(uint16_t conn_handle)
|
||||
{
|
||||
if (!g_bonding_in_progress)
|
||||
{
|
||||
g_bonding_in_progress = true;
|
||||
ESP_LOGI(TAG, "Initiating bonding for connection %d", conn_handle);
|
||||
|
||||
// Starte Security/Bonding Prozess
|
||||
int rc = ble_gap_security_initiate(conn_handle);
|
||||
if (rc != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to initiate security: %s", ble_error_to_string(rc));
|
||||
g_bonding_in_progress = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int gattc_svcs_callback(uint16_t conn_handle, const struct ble_gatt_error *error,
|
||||
const struct ble_gatt_svc *service, void *arg)
|
||||
{
|
||||
if (error->status != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Error discovering service: %s", ble_error_to_string(error->status));
|
||||
return 0;
|
||||
}
|
||||
|
||||
char uuid_str[37]; // Maximale Länge für 128-bit UUID
|
||||
ble_uuid_to_str(&service->uuid.u, uuid_str);
|
||||
ESP_LOGI(TAG, "Discovered service: %s", uuid_str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gattc_char_callback(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_chr *chr,
|
||||
void *arg)
|
||||
{
|
||||
if (error->status != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Error discovering characteristic: %d", error->status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_char_val_handle = chr->val_handle;
|
||||
read_characteristic(chr->val_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Callback für GATT-Events
|
||||
static int gattc_event_callback(uint16_t conn_handle, const struct ble_gatt_error *error,
|
||||
const struct ble_gatt_svc *service, void *arg)
|
||||
{
|
||||
if (error->status != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Error discovering service: %d", error->status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ble_gattc_disc_all_svcs(conn_handle, gattc_svcs_callback, NULL);
|
||||
// ble_gattc_disc_all_chrs(conn_handle, service->start_handle, service->end_handle, gattc_char_callback, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gattc_read_callback(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr,
|
||||
void *arg)
|
||||
{
|
||||
if (error->status == 0)
|
||||
{
|
||||
ESP_LOGI(TAG, "Wert gelesen %d, Länge: %d", attr->handle, attr->om->om_len);
|
||||
ESP_LOG_BUFFER_HEX("READ_DATA", attr->om->om_data, attr->om->om_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Lesefehler, Status: %d", error->status);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ble_gap_event_handler(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
device_info_t *device = (device_info_t *)arg;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case BLE_GAP_EVENT_CONNECT:
|
||||
if (event->connect.status == 0)
|
||||
{
|
||||
g_conn_handle = event->connect.conn_handle;
|
||||
ESP_LOGI(TAG, "Connected; conn_handle=%d", g_conn_handle);
|
||||
|
||||
// Prüfe ob Device bereits gebondet ist
|
||||
if (is_device_bonded(&device->addr))
|
||||
{
|
||||
ESP_LOGI(TAG, "Device already bonded, using existing bond");
|
||||
// Bei gebondetem Device kann direkt mit Service Discovery begonnen werden
|
||||
ble_gattc_disc_all_svcs(g_conn_handle, gattc_event_callback, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Device not bonded, initiating bonding");
|
||||
// Starte Bonding-Prozess
|
||||
initiate_bonding(g_conn_handle);
|
||||
// Service Discovery wird nach erfolgreichem Bonding gestartet
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Connection failed; status=%d", event->connect.status);
|
||||
}
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_DISCONNECT:
|
||||
g_conn_handle = 0;
|
||||
g_bonding_in_progress = false;
|
||||
ESP_LOGI(TAG, "Disconnected; reason=%d", event->disconnect.reason);
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE:
|
||||
ESP_LOGI(TAG, "Connection updated; status=%d", event->conn_update.status);
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_ENC_CHANGE:
|
||||
ESP_LOGI(TAG, "Encryption change: status=%d", event->enc_change.status);
|
||||
if (event->enc_change.status == 0)
|
||||
{
|
||||
ESP_LOGI(TAG, "Encryption established, bonding complete");
|
||||
g_bonding_in_progress = false;
|
||||
// Nach erfolgreichem Bonding: Service Discovery starten
|
||||
ble_gattc_disc_all_svcs(g_conn_handle, gattc_event_callback, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Encryption failed: %s", ble_error_to_string(event->enc_change.status));
|
||||
g_bonding_in_progress = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_PASSKEY_ACTION:
|
||||
ESP_LOGI(TAG, "Passkey action event");
|
||||
// Implementieren Sie hier die Passkey-Behandlung
|
||||
// z.B. einen festen Passkey eingeben:
|
||||
struct ble_sm_io pkey = {0};
|
||||
pkey.action = BLE_SM_IOACT_INPUT;
|
||||
pkey.passkey = 100779;
|
||||
ble_sm_inject_io(event->passkey.conn_handle, &pkey);
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_REPEAT_PAIRING:
|
||||
ESP_LOGI(TAG, "Device requests repeat pairing");
|
||||
|
||||
// Hole die Peer-Adresse aus der Verbindung
|
||||
struct ble_gap_conn_desc conn_desc;
|
||||
int rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &conn_desc);
|
||||
if (rc == 0)
|
||||
{
|
||||
// Lösche alte Bonding-Info
|
||||
ble_clear_bond(&conn_desc.peer_ota_addr);
|
||||
}
|
||||
|
||||
// Erlaube erneutes Pairing
|
||||
return BLE_GAP_REPEAT_PAIRING_RETRY;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ble_connect(device_info_t *device)
|
||||
{
|
||||
struct ble_gap_conn_params conn_params = {
|
||||
.scan_itvl = 0x0010,
|
||||
.scan_window = 0x0010,
|
||||
.itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN,
|
||||
.itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX,
|
||||
.latency = BLE_GAP_INITIAL_CONN_LATENCY,
|
||||
.supervision_timeout = BLE_GAP_INITIAL_SUPERVISION_TIMEOUT,
|
||||
.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN,
|
||||
.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN,
|
||||
};
|
||||
|
||||
// Prüfe ob Device bereits gebondet ist
|
||||
if (is_device_bonded(&device->addr))
|
||||
{
|
||||
ESP_LOGI(TAG, "Connecting to bonded device");
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Connecting to new device (will bond after connection)");
|
||||
}
|
||||
|
||||
int rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &device->addr, 30000, &conn_params, ble_gap_event_handler, device);
|
||||
if (rc != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Error initiating connection: %s", ble_error_to_string(rc));
|
||||
}
|
||||
}
|
||||
|
||||
void ble_clear_bonds(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Clearing all bonds");
|
||||
|
||||
int rc = ble_store_clear();
|
||||
if (rc != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to clear bond storage: %s", ble_error_to_string(rc));
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "All bonds cleared successfully");
|
||||
}
|
||||
}
|
||||
|
||||
// Funktion zum Löschen der Bonding-Info eines bestimmten Devices
|
||||
void ble_clear_bond(const ble_addr_t *addr)
|
||||
{
|
||||
ESP_LOGI(TAG, "Clearing bond for specific device");
|
||||
|
||||
int rc = ble_store_util_delete_peer(addr);
|
||||
if (rc != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to delete peer: %s", ble_error_to_string(rc));
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Peer deleted successfully");
|
||||
}
|
||||
}
|
||||
|
||||
void read_characteristic(uint16_t char_val_handle)
|
||||
{
|
||||
if (char_val_handle != 0 && g_conn_handle != 0)
|
||||
{
|
||||
int rc = ble_gattc_read(g_conn_handle, char_val_handle, gattc_read_callback, NULL);
|
||||
if (rc != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Error reading characteristic: %d", rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
324
firmware/components/connectivity-manager/src/ble/ble_scanner.c
Normal file
324
firmware/components/connectivity-manager/src/ble/ble_scanner.c
Normal file
@@ -0,0 +1,324 @@
|
||||
#include "ble/ble_scanner.h"
|
||||
|
||||
#include "ble/ble_device.h"
|
||||
#include "led_status.h"
|
||||
#include <esp_log.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <host/ble_hs.h>
|
||||
#include <host/util/util.h>
|
||||
#include <nimble/nimble_port.h>
|
||||
#include <nimble/nimble_port_freertos.h>
|
||||
#include <services/gap/ble_svc_gap.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static const char *TAG = "ble_scanner";
|
||||
|
||||
// List of allowed manufacturer IDs
|
||||
static const uint16_t ALLOWED_MANUFACTURERS[] = {
|
||||
0xC0DE, // mars3142
|
||||
};
|
||||
static const size_t NUM_MANUFACTURERS = sizeof(ALLOWED_MANUFACTURERS) / sizeof(uint16_t);
|
||||
static bool scanning = false;
|
||||
|
||||
static bool is_manufacturer_allowed(uint16_t company_id)
|
||||
{
|
||||
for (size_t i = 0; i < NUM_MANUFACTURERS; i++)
|
||||
{
|
||||
if (ALLOWED_MANUFACTURERS[i] == company_id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ble_central_gap_event(struct ble_gap_event *event, void *arg);
|
||||
|
||||
/**
|
||||
* Starts the BLE scan process.
|
||||
*/
|
||||
void start_scan(void)
|
||||
{
|
||||
led_behavior_t led_behavior = {
|
||||
.on_time_ms = 200,
|
||||
.off_time_ms = 200,
|
||||
.color = {.red = 0, .green = 0, .blue = 50},
|
||||
.index = 1,
|
||||
.mode = LED_MODE_BLINK,
|
||||
};
|
||||
led_status_set_behavior(led_behavior);
|
||||
|
||||
struct ble_gap_disc_params disc_params = {
|
||||
.filter_policy = 0,
|
||||
.limited = 0,
|
||||
.passive = 0,
|
||||
.filter_duplicates = 1,
|
||||
};
|
||||
|
||||
int32_t duration_ms = 10000; // 10 seconds
|
||||
|
||||
int rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, duration_ms, &disc_params, ble_central_gap_event, NULL);
|
||||
if (rc != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Error starting scan; rc=%d", rc);
|
||||
}
|
||||
scanning = true;
|
||||
}
|
||||
|
||||
#define MAX_DEVICES 40
|
||||
static device_info_t devices[MAX_DEVICES];
|
||||
static int device_count = 0;
|
||||
|
||||
// Helper function to find or create a device entry
|
||||
static device_info_t *find_or_create_device(const ble_addr_t *addr)
|
||||
{
|
||||
// Search for existing device
|
||||
for (int i = 0; i < device_count; i++)
|
||||
{
|
||||
if (memcmp(&devices[i].addr, addr, sizeof(ble_addr_t)) == 0)
|
||||
{
|
||||
return &devices[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Add new device
|
||||
if (device_count < MAX_DEVICES)
|
||||
{
|
||||
memset(&devices[device_count], 0, sizeof(device_info_t));
|
||||
memcpy(&devices[device_count].addr, addr, sizeof(ble_addr_t));
|
||||
devices[device_count].has_manufacturer = false;
|
||||
devices[device_count].has_name = false;
|
||||
strcpy(devices[device_count].name, "Unknown");
|
||||
return &devices[device_count++];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ble_central_gap_event(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
struct ble_gap_disc_desc *disc;
|
||||
struct ble_hs_adv_fields fields;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case BLE_GAP_EVENT_DISC: {
|
||||
disc = &event->disc;
|
||||
|
||||
// Find or create device
|
||||
device_info_t *device = find_or_create_device(&disc->addr);
|
||||
if (device == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Update RSSI
|
||||
device->rssi = disc->rssi;
|
||||
|
||||
// Parse advertising data
|
||||
memset(&fields, 0, sizeof(fields));
|
||||
ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data);
|
||||
|
||||
// Process manufacturer data
|
||||
if (fields.mfg_data != NULL && fields.mfg_data_len >= 2)
|
||||
{
|
||||
uint16_t company_id = fields.mfg_data[0] | (fields.mfg_data[1] << 8);
|
||||
device->manufacturer_id = company_id;
|
||||
device->has_manufacturer = true;
|
||||
|
||||
// Store complete manufacturer data (incl. Company ID)
|
||||
device->manufacturer_data_len = fields.mfg_data_len;
|
||||
memcpy(device->manufacturer_data, fields.mfg_data, fields.mfg_data_len);
|
||||
}
|
||||
|
||||
// Process name
|
||||
if (fields.name != NULL && fields.name_len > 0)
|
||||
{
|
||||
size_t copy_len = fields.name_len < sizeof(device->name) - 1 ? fields.name_len : sizeof(device->name) - 1;
|
||||
memcpy(device->name, fields.name, copy_len);
|
||||
device->name[copy_len] = '\0';
|
||||
device->has_name = true;
|
||||
}
|
||||
|
||||
// Process 16-bit Service UUIDs
|
||||
if (fields.uuids16 != NULL && fields.num_uuids16 > 0)
|
||||
{
|
||||
for (int i = 0; i < fields.num_uuids16 && device->service_uuids_16_count < 10; i++)
|
||||
{
|
||||
// Check if UUID already exists
|
||||
bool exists = false;
|
||||
for (int j = 0; j < device->service_uuids_16_count; j++)
|
||||
{
|
||||
if (device->service_uuids_16[j] == fields.uuids16[i].value)
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!exists)
|
||||
{
|
||||
device->service_uuids_16[device->service_uuids_16_count++] = fields.uuids16[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process 128-bit Service UUIDs
|
||||
if (fields.uuids128 != NULL && fields.num_uuids128 > 0)
|
||||
{
|
||||
for (int i = 0; i < fields.num_uuids128 && device->service_uuids_128_count < 5; i++)
|
||||
{
|
||||
// Check if UUID already exists
|
||||
bool exists = false;
|
||||
for (int j = 0; j < device->service_uuids_128_count; j++)
|
||||
{
|
||||
if (memcmp(&device->service_uuids_128[j], &fields.uuids128[i], sizeof(ble_uuid128_t)) == 0)
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!exists)
|
||||
{
|
||||
memcpy(&device->service_uuids_128[device->service_uuids_128_count++], &fields.uuids128[i],
|
||||
sizeof(ble_uuid128_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we have all data and the device is allowed
|
||||
if (device->has_name && device->has_manufacturer && is_manufacturer_allowed(device->manufacturer_id))
|
||||
{
|
||||
ESP_LOGI(TAG, "*** Allowed device found ***");
|
||||
ESP_LOGI(TAG, " Name: %s", device->name);
|
||||
ESP_LOGI(TAG, " Address: %02X:%02X:%02X:%02X:%02X:%02X", device->addr.val[5], device->addr.val[4],
|
||||
device->addr.val[3], device->addr.val[2], device->addr.val[1], device->addr.val[0]);
|
||||
ESP_LOGI(TAG, " Manufacturer ID: 0x%04X", device->manufacturer_id);
|
||||
ESP_LOGI(TAG, " RSSI: %d dBm", device->rssi);
|
||||
|
||||
// Print Service UUIDs
|
||||
if (device->service_uuids_16_count > 0)
|
||||
{
|
||||
ESP_LOGI(TAG, " 16-bit Service UUIDs (%d):", device->service_uuids_16_count);
|
||||
for (int i = 0; i < device->service_uuids_16_count; i++)
|
||||
{
|
||||
const char *name = "";
|
||||
// Known Service UUIDs
|
||||
switch (device->service_uuids_16[i])
|
||||
{
|
||||
case 0x180A:
|
||||
name = " (Device Information)";
|
||||
break;
|
||||
case 0x180F:
|
||||
name = " (Battery Service)";
|
||||
break;
|
||||
case 0x1801:
|
||||
name = " (Generic Attribute)";
|
||||
break;
|
||||
case 0x1800:
|
||||
name = " (Generic Access)";
|
||||
break;
|
||||
case 0x181A:
|
||||
name = " (Environmental Sensing)";
|
||||
break;
|
||||
default:
|
||||
if (device->service_uuids_16[i] >= 0xA000)
|
||||
{
|
||||
name = " (Custom)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(TAG, " - 0x%04X%s", device->service_uuids_16[i], name);
|
||||
}
|
||||
}
|
||||
|
||||
if (device->service_uuids_128_count > 0)
|
||||
{
|
||||
ESP_LOGI(TAG, " 128-bit Service UUIDs (%d):", device->service_uuids_128_count);
|
||||
for (int i = 0; i < device->service_uuids_128_count; i++)
|
||||
{
|
||||
char uuid_str[37]; // UUID string format
|
||||
snprintf(uuid_str, sizeof(uuid_str),
|
||||
"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
device->service_uuids_128[i].value[15], device->service_uuids_128[i].value[14],
|
||||
device->service_uuids_128[i].value[13], device->service_uuids_128[i].value[12],
|
||||
device->service_uuids_128[i].value[11], device->service_uuids_128[i].value[10],
|
||||
device->service_uuids_128[i].value[9], device->service_uuids_128[i].value[8],
|
||||
device->service_uuids_128[i].value[7], device->service_uuids_128[i].value[6],
|
||||
device->service_uuids_128[i].value[5], device->service_uuids_128[i].value[4],
|
||||
device->service_uuids_128[i].value[3], device->service_uuids_128[i].value[2],
|
||||
device->service_uuids_128[i].value[1], device->service_uuids_128[i].value[0]);
|
||||
ESP_LOGI(TAG, " - %s", uuid_str);
|
||||
}
|
||||
}
|
||||
|
||||
// Print manufacturer data (without Company ID, i.e., from byte 2)
|
||||
if (device->manufacturer_data_len > 2)
|
||||
{
|
||||
int payload_len = device->manufacturer_data_len - 2;
|
||||
ESP_LOGI(TAG, " Manufacturer Data (%d bytes):", payload_len);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(TAG, &device->manufacturer_data[2], payload_len, ESP_LOG_INFO);
|
||||
|
||||
// Print data byte by byte for better readability
|
||||
ESP_LOGI(TAG, " Data interpretation:");
|
||||
for (int i = 0; i < payload_len; i++)
|
||||
{
|
||||
ESP_LOGI(TAG, " - Byte %d: 0x%02X (%d)", i, device->manufacturer_data[i + 2],
|
||||
device->manufacturer_data[i + 2]);
|
||||
}
|
||||
|
||||
// Optional: Interpret data as 16-bit values (if the number of bytes is even)
|
||||
if (payload_len >= 2 && (payload_len % 2 == 0))
|
||||
{
|
||||
ESP_LOGI(TAG, " As 16-bit values:");
|
||||
for (int i = 0; i < payload_len; i += 2)
|
||||
{
|
||||
uint16_t value = device->manufacturer_data[i + 2] | (device->manufacturer_data[i + 3] << 8);
|
||||
ESP_LOGI(TAG, " - Word %d: 0x%04X (%d)", i / 2, value, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, " No manufacturer payload data");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case BLE_GAP_EVENT_DISC_COMPLETE: {
|
||||
led_behavior_t led_behavior = {
|
||||
.index = 1,
|
||||
.mode = LED_MODE_OFF,
|
||||
};
|
||||
led_status_set_behavior(led_behavior);
|
||||
|
||||
ESP_LOGI(TAG, "Discovery complete");
|
||||
scanning = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_info_t *get_device(int index)
|
||||
{
|
||||
if (index < 0 || index >= device_count || !is_manufacturer_allowed(devices[index].manufacturer_id))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return &devices[index];
|
||||
}
|
||||
|
||||
int get_device_count(void)
|
||||
{
|
||||
if (!scanning)
|
||||
{
|
||||
return device_count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,312 +1,23 @@
|
||||
#include "ble_manager.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "host/ble_hs.h"
|
||||
#include "host/util/util.h"
|
||||
#include "nimble/nimble_port.h"
|
||||
#include "nimble/nimble_port_freertos.h"
|
||||
#include "services/gap/ble_svc_gap.h"
|
||||
|
||||
#include "ble/ble_connection.h"
|
||||
#include "ble/ble_scanner.h"
|
||||
#include <esp_log.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <host/ble_hs.h>
|
||||
#include <host/util/util.h>
|
||||
#include <nimble/nimble_port.h>
|
||||
#include <nimble/nimble_port_freertos.h>
|
||||
#include <services/gap/ble_svc_gap.h>
|
||||
|
||||
static const char *TAG = "ble_manager";
|
||||
|
||||
// List of allowed manufacturer IDs
|
||||
static const uint16_t ALLOWED_MANUFACTURERS[] = {
|
||||
0xC0DE, // mars3142
|
||||
};
|
||||
static const size_t NUM_MANUFACTURERS = sizeof(ALLOWED_MANUFACTURERS) / sizeof(uint16_t);
|
||||
|
||||
// Structure to cache device data
|
||||
typedef struct
|
||||
{
|
||||
ble_addr_t addr;
|
||||
uint16_t manufacturer_id;
|
||||
uint8_t manufacturer_data[31]; // Max. length of manufacturer data
|
||||
uint8_t manufacturer_data_len;
|
||||
char name[32];
|
||||
uint16_t service_uuids_16[10]; // Up to 10 16-bit Service UUIDs
|
||||
uint8_t service_uuids_16_count;
|
||||
ble_uuid128_t service_uuids_128[5]; // Up to 5 128-bit Service UUIDs
|
||||
uint8_t service_uuids_128_count;
|
||||
bool has_manufacturer;
|
||||
bool has_name;
|
||||
int8_t rssi;
|
||||
} device_info_t;
|
||||
|
||||
static bool is_manufacturer_allowed(uint16_t company_id)
|
||||
{
|
||||
for (size_t i = 0; i < NUM_MANUFACTURERS; i++)
|
||||
{
|
||||
if (ALLOWED_MANUFACTURERS[i] == company_id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ble_central_gap_event(struct ble_gap_event *event, void *arg);
|
||||
|
||||
/**
|
||||
* Starts the BLE scan process.
|
||||
*/
|
||||
static void start_scan(void)
|
||||
{
|
||||
struct ble_gap_disc_params disc_params = {
|
||||
.filter_policy = 0,
|
||||
.limited = 0,
|
||||
.passive = 0,
|
||||
.filter_duplicates = 1,
|
||||
};
|
||||
|
||||
int rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &disc_params, ble_central_gap_event, NULL);
|
||||
if (rc != 0)
|
||||
{
|
||||
ESP_LOGE(TAG, "Error starting scan; rc=%d", rc);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_DEVICES 10
|
||||
static device_info_t devices[MAX_DEVICES];
|
||||
static int device_count = 0;
|
||||
|
||||
// Helper function to find or create a device entry
|
||||
static device_info_t *find_or_create_device(const ble_addr_t *addr)
|
||||
{
|
||||
// Search for existing device
|
||||
for (int i = 0; i < device_count; i++)
|
||||
{
|
||||
if (memcmp(&devices[i].addr, addr, sizeof(ble_addr_t)) == 0)
|
||||
{
|
||||
return &devices[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Add new device
|
||||
if (device_count < MAX_DEVICES)
|
||||
{
|
||||
memset(&devices[device_count], 0, sizeof(device_info_t));
|
||||
memcpy(&devices[device_count].addr, addr, sizeof(ble_addr_t));
|
||||
devices[device_count].has_manufacturer = false;
|
||||
devices[device_count].has_name = false;
|
||||
strcpy(devices[device_count].name, "Unknown");
|
||||
return &devices[device_count++];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ble_central_gap_event(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
struct ble_gap_disc_desc *disc;
|
||||
struct ble_hs_adv_fields fields;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case BLE_GAP_EVENT_DISC: {
|
||||
disc = &event->disc;
|
||||
|
||||
// Find or create device
|
||||
device_info_t *device = find_or_create_device(&disc->addr);
|
||||
if (device == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Update RSSI
|
||||
device->rssi = disc->rssi;
|
||||
|
||||
// Parse advertising data
|
||||
memset(&fields, 0, sizeof(fields));
|
||||
ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data);
|
||||
|
||||
// Process manufacturer data
|
||||
if (fields.mfg_data != NULL && fields.mfg_data_len >= 2)
|
||||
{
|
||||
uint16_t company_id = fields.mfg_data[0] | (fields.mfg_data[1] << 8);
|
||||
device->manufacturer_id = company_id;
|
||||
device->has_manufacturer = true;
|
||||
|
||||
// Store complete manufacturer data (incl. Company ID)
|
||||
device->manufacturer_data_len = fields.mfg_data_len;
|
||||
memcpy(device->manufacturer_data, fields.mfg_data, fields.mfg_data_len);
|
||||
}
|
||||
|
||||
// Process name
|
||||
if (fields.name != NULL && fields.name_len > 0)
|
||||
{
|
||||
size_t copy_len = fields.name_len < sizeof(device->name) - 1 ? fields.name_len : sizeof(device->name) - 1;
|
||||
memcpy(device->name, fields.name, copy_len);
|
||||
device->name[copy_len] = '\0';
|
||||
device->has_name = true;
|
||||
}
|
||||
|
||||
// Process 16-bit Service UUIDs
|
||||
if (fields.uuids16 != NULL && fields.num_uuids16 > 0)
|
||||
{
|
||||
for (int i = 0; i < fields.num_uuids16 && device->service_uuids_16_count < 10; i++)
|
||||
{
|
||||
// Check if UUID already exists
|
||||
bool exists = false;
|
||||
for (int j = 0; j < device->service_uuids_16_count; j++)
|
||||
{
|
||||
if (device->service_uuids_16[j] == fields.uuids16[i].value)
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!exists)
|
||||
{
|
||||
device->service_uuids_16[device->service_uuids_16_count++] = fields.uuids16[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process 128-bit Service UUIDs
|
||||
if (fields.uuids128 != NULL && fields.num_uuids128 > 0)
|
||||
{
|
||||
for (int i = 0; i < fields.num_uuids128 && device->service_uuids_128_count < 5; i++)
|
||||
{
|
||||
// Check if UUID already exists
|
||||
bool exists = false;
|
||||
for (int j = 0; j < device->service_uuids_128_count; j++)
|
||||
{
|
||||
if (memcmp(&device->service_uuids_128[j], &fields.uuids128[i], sizeof(ble_uuid128_t)) == 0)
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!exists)
|
||||
{
|
||||
memcpy(&device->service_uuids_128[device->service_uuids_128_count++], &fields.uuids128[i],
|
||||
sizeof(ble_uuid128_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we have all data and the device is allowed
|
||||
if (device->has_manufacturer && is_manufacturer_allowed(device->manufacturer_id))
|
||||
{
|
||||
ESP_LOGI(TAG, "*** Allowed device found ***");
|
||||
ESP_LOGI(TAG, " Name: %s", device->name);
|
||||
ESP_LOGI(TAG, " Address: %02X:%02X:%02X:%02X:%02X:%02X", device->addr.val[5], device->addr.val[4],
|
||||
device->addr.val[3], device->addr.val[2], device->addr.val[1], device->addr.val[0]);
|
||||
ESP_LOGI(TAG, " Manufacturer ID: 0x%04X", device->manufacturer_id);
|
||||
ESP_LOGI(TAG, " RSSI: %d dBm", device->rssi);
|
||||
|
||||
// Print Service UUIDs
|
||||
if (device->service_uuids_16_count > 0)
|
||||
{
|
||||
ESP_LOGI(TAG, " 16-bit Service UUIDs (%d):", device->service_uuids_16_count);
|
||||
for (int i = 0; i < device->service_uuids_16_count; i++)
|
||||
{
|
||||
const char *name = "";
|
||||
// Known Service UUIDs
|
||||
switch (device->service_uuids_16[i])
|
||||
{
|
||||
case 0x180A:
|
||||
name = " (Device Information)";
|
||||
break;
|
||||
case 0x180F:
|
||||
name = " (Battery Service)";
|
||||
break;
|
||||
case 0x1801:
|
||||
name = " (Generic Attribute)";
|
||||
break;
|
||||
case 0x1800:
|
||||
name = " (Generic Access)";
|
||||
break;
|
||||
case 0x181A:
|
||||
name = " (Environmental Sensing)";
|
||||
break;
|
||||
default:
|
||||
if (device->service_uuids_16[i] >= 0xA000)
|
||||
{
|
||||
name = " (Custom)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(TAG, " - 0x%04X%s", device->service_uuids_16[i], name);
|
||||
}
|
||||
}
|
||||
|
||||
if (device->service_uuids_128_count > 0)
|
||||
{
|
||||
ESP_LOGI(TAG, " 128-bit Service UUIDs (%d):", device->service_uuids_128_count);
|
||||
for (int i = 0; i < device->service_uuids_128_count; i++)
|
||||
{
|
||||
char uuid_str[37]; // UUID string format
|
||||
snprintf(uuid_str, sizeof(uuid_str),
|
||||
"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
device->service_uuids_128[i].value[15], device->service_uuids_128[i].value[14],
|
||||
device->service_uuids_128[i].value[13], device->service_uuids_128[i].value[12],
|
||||
device->service_uuids_128[i].value[11], device->service_uuids_128[i].value[10],
|
||||
device->service_uuids_128[i].value[9], device->service_uuids_128[i].value[8],
|
||||
device->service_uuids_128[i].value[7], device->service_uuids_128[i].value[6],
|
||||
device->service_uuids_128[i].value[5], device->service_uuids_128[i].value[4],
|
||||
device->service_uuids_128[i].value[3], device->service_uuids_128[i].value[2],
|
||||
device->service_uuids_128[i].value[1], device->service_uuids_128[i].value[0]);
|
||||
ESP_LOGI(TAG, " - %s", uuid_str);
|
||||
}
|
||||
}
|
||||
|
||||
// Print manufacturer data (without Company ID, i.e., from byte 2)
|
||||
if (device->manufacturer_data_len > 2)
|
||||
{
|
||||
int payload_len = device->manufacturer_data_len - 2;
|
||||
ESP_LOGI(TAG, " Manufacturer Data (%d bytes):", payload_len);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(TAG, &device->manufacturer_data[2], payload_len, ESP_LOG_INFO);
|
||||
|
||||
// Print data byte by byte for better readability
|
||||
ESP_LOGI(TAG, " Data interpretation:");
|
||||
for (int i = 0; i < payload_len; i++)
|
||||
{
|
||||
ESP_LOGI(TAG, " - Byte %d: 0x%02X (%d)", i, device->manufacturer_data[i + 2],
|
||||
device->manufacturer_data[i + 2]);
|
||||
}
|
||||
|
||||
// Optional: Interpret data as 16-bit values (if the number of bytes is even)
|
||||
if (payload_len >= 2 && (payload_len % 2 == 0))
|
||||
{
|
||||
ESP_LOGI(TAG, " As 16-bit values:");
|
||||
for (int i = 0; i < payload_len; i += 2)
|
||||
{
|
||||
uint16_t value = device->manufacturer_data[i + 2] | (device->manufacturer_data[i + 3] << 8);
|
||||
ESP_LOGI(TAG, " - Word %d: 0x%04X (%d)", i / 2, value, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, " No manufacturer payload data");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case BLE_GAP_EVENT_DISC_COMPLETE: {
|
||||
ESP_LOGI(TAG, "Discovery complete, restarting scan...");
|
||||
// Optional: Reset device list
|
||||
device_count = 0;
|
||||
start_scan();
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback that is called when the NimBLE stack is synchronized and ready.
|
||||
*/
|
||||
static void on_sync(void)
|
||||
{
|
||||
// The stack is ready, we can start the scan.
|
||||
start_scan();
|
||||
}
|
||||
|
||||
@@ -333,3 +44,17 @@ void ble_manager_task(void *pvParameter)
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
bool ble_found_devices(void)
|
||||
{
|
||||
return get_device_count() > 0;
|
||||
}
|
||||
|
||||
void ble_connect_to_device(int index)
|
||||
{
|
||||
device_info_t *device = get_device(index);
|
||||
if (device != NULL)
|
||||
{
|
||||
ble_connect(device);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#include "wifi_manager.h"
|
||||
|
||||
#include "esp_event.h"
|
||||
#include "esp_insights.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "freertos/task.h"
|
||||
#include "led_status.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "sdkconfig.h"
|
||||
#include <esp_event.h>
|
||||
#include <esp_insights.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_system.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/event_groups.h>
|
||||
#include <freertos/task.h>
|
||||
#include <led_status.h>
|
||||
#include <lwip/err.h>
|
||||
#include <lwip/sys.h>
|
||||
#include <nvs_flash.h>
|
||||
#include <sdkconfig.h>
|
||||
|
||||
// Event group to signal when we are connected
|
||||
static EventGroupHandle_t s_wifi_event_group;
|
||||
@@ -30,11 +30,14 @@ static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_
|
||||
#if CONFIG_WIFI_ENABLED
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
|
||||
{
|
||||
led_behavior_t led0_behavior = {.mode = LED_MODE_BLINK,
|
||||
.color = {.red = 50, .green = 50, .blue = 0},
|
||||
.on_time_ms = 200,
|
||||
.off_time_ms = 200};
|
||||
led_status_set_behavior(0, led0_behavior);
|
||||
led_behavior_t led0_behavior = {
|
||||
.index = 0,
|
||||
.mode = LED_MODE_BLINK,
|
||||
.color = {.red = 50, .green = 50, .blue = 0},
|
||||
.on_time_ms = 200,
|
||||
.off_time_ms = 200,
|
||||
};
|
||||
led_status_set_behavior(led0_behavior);
|
||||
|
||||
esp_wifi_connect();
|
||||
}
|
||||
@@ -42,32 +45,39 @@ static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_
|
||||
{
|
||||
if (s_retry_num < CONFIG_WIFI_CONNECT_RETRIES)
|
||||
{
|
||||
led_behavior_t led0_behavior = {.mode = LED_MODE_BLINK,
|
||||
.color = {.red = 50, .green = 50, .blue = 0},
|
||||
.on_time_ms = 200,
|
||||
.off_time_ms = 200};
|
||||
led_status_set_behavior(0, led0_behavior);
|
||||
led_behavior_t led0_behavior = {
|
||||
.index = 0,
|
||||
.mode = LED_MODE_BLINK,
|
||||
.color = {.red = 50, .green = 50, .blue = 0},
|
||||
.on_time_ms = 200,
|
||||
.off_time_ms = 200,
|
||||
};
|
||||
led_status_set_behavior(led0_behavior);
|
||||
|
||||
esp_wifi_connect();
|
||||
s_retry_num++;
|
||||
ESP_DIAG_EVENT(TAG, "Retrying to connect to the AP");
|
||||
return;
|
||||
}
|
||||
led_behavior_t led0_behavior = {.mode = LED_MODE_BLINK,
|
||||
.color = {.red = 50, .green = 0, .blue = 0},
|
||||
.on_time_ms = 1000,
|
||||
.off_time_ms = 500};
|
||||
led_status_set_behavior(0, led0_behavior);
|
||||
led_behavior_t led0_behavior = {
|
||||
.index = 0,
|
||||
.mode = LED_MODE_BLINK,
|
||||
.color = {.red = 50, .green = 0, .blue = 0},
|
||||
.on_time_ms = 1000,
|
||||
.off_time_ms = 500,
|
||||
};
|
||||
led_status_set_behavior(led0_behavior);
|
||||
|
||||
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
|
||||
}
|
||||
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
|
||||
{
|
||||
led_behavior_t led0_behavior = {
|
||||
.index = 0,
|
||||
.mode = LED_MODE_SOLID,
|
||||
.color = {.red = 0, .green = 50, .blue = 0},
|
||||
};
|
||||
led_status_set_behavior(0, led0_behavior);
|
||||
led_status_set_behavior(led0_behavior);
|
||||
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||
ESP_DIAG_EVENT(TAG, "Got IP address:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||
|
||||
Reference in New Issue
Block a user