Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 22 additions & 17 deletions ot_br/components/ot_br_web_api/ot_br_web_api_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@
// CoAP Light Control
#include "ot_br_web_api_coap_client.h"

// static const char *TAG = "ot_br_web_handlers";
static const char *TAG = "ot_br_web_api_handlers";

extern bool ot_br_web_api_check_auth(httpd_req_t *req);

static SemaphoreHandle_t s_commissioner_active_sem = NULL;

// -------- Helpers --------

void send_json(httpd_req_t *req, cJSON *json)
Expand Down Expand Up @@ -545,6 +547,14 @@ static esp_err_t setup_complete_handler(httpd_req_t *req)
return ESP_OK;
}


static void commissioner_state_callback(otCommissionerState state, void *context)
{
if (state == OT_COMMISSIONER_STATE_ACTIVE) {
xSemaphoreGive(s_commissioner_active_sem);
}
}

// POST /api/thread/commissioner/open
// Body: {"pskd": "J01NME"}
// Fuehrt Stop+Start+Joiner-Add in EINEM atomaren Aufruf aus - verhindert
Expand Down Expand Up @@ -578,33 +588,28 @@ static esp_err_t commissioner_open_handler(httpd_req_t *req)
pskd[sizeof(pskd) - 1] = '\0';
cJSON_Delete(json);

if (!s_commissioner_active_sem) {
s_commissioner_active_sem = xSemaphoreCreateBinary();
}
xSemaphoreTake(s_commissioner_active_sem, 0); // evtl. Altsignal verwerfen

otInstance *instance = otInstanceInitSingle();

esp_openthread_lock_acquire(portMAX_DELAY);
// Workaround fuer bekannten ESP-IDF-Bug (Issue #18075):
// Stop-vor-Start behebt "Failed to process Discovery Request: Security"
otCommissionerStop(instance);
otError start_err = otCommissionerStart(instance, NULL, NULL, NULL);
otError start_err = otCommissionerStart(instance, commissioner_state_callback, NULL, NULL);
esp_openthread_lock_release();

otError joiner_err = OT_ERROR_INVALID_STATE;
if (start_err == OT_ERROR_NONE) {
// Commissioner braucht einen Moment fuer den Uebergang
// petitioning -> active, bevor AddJoiner erfolgreich sein kann
for (int i = 0; i < 20; i++) { // max. 2 Sekunden warten
// Waiting, until the State-Callback returns ACTIVE instead of Polling
if (xSemaphoreTake(s_commissioner_active_sem, pdMS_TO_TICKS(5000)) == pdTRUE) {
esp_openthread_lock_acquire(portMAX_DELAY);
otCommissionerState state = otCommissionerGetState(instance);
joiner_err = otCommissionerAddJoiner(instance, NULL, pskd, 600);
esp_openthread_lock_release();

if (state == OT_COMMISSIONER_STATE_ACTIVE) {
break;
}
vTaskDelay(pdMS_TO_TICKS(100));
} else {
ESP_LOGW(TAG, "Timeout while waiting on the ACTIVE-state");
}

esp_openthread_lock_acquire(portMAX_DELAY);
joiner_err = otCommissionerAddJoiner(instance, NULL, pskd, 0);
esp_openthread_lock_release();
}

if (start_err != OT_ERROR_NONE || joiner_err != OT_ERROR_NONE) {
Expand Down
66 changes: 49 additions & 17 deletions ot_br/components/ot_br_web_api/ot_br_web_api_setup_mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,59 @@ static const char *TAG = "ot_br_setup_mode";
static volatile bool s_setup_mode_active = false;
static int64_t s_setup_mode_started_at = 0;

static void commissioner_state_callback(otCommissionerState aState, void *aContext)
{
switch (aState)
{
case OT_COMMISSIONER_STATE_ACTIVE:
ESP_LOGI(TAG, "Commissioner ACTIVE");
break;

case OT_COMMISSIONER_STATE_PETITION:
ESP_LOGI(TAG, "Commissioner PETITION");
break;

case OT_COMMISSIONER_STATE_DISABLED:
ESP_LOGI(TAG, "Commissioner DISABLED");
break;

default:
ESP_LOGI(TAG, "Commissioner state: %d", aState);
break;
}
}

static void auto_open_commissioning(void)
{
otInstance *instance = esp_openthread_get_instance();
esp_openthread_lock_acquire(portMAX_DELAY);
otCommissionerStop(instance);
otError err = otCommissionerStart(instance, NULL, NULL, NULL);

otError err;

if (otCommissionerGetState(instance) != OT_COMMISSIONER_STATE_DISABLED)
{
ESP_LOGW(TAG, "Commissioner already active - stopping first");

err = otCommissionerStop(instance);

ESP_LOGI(TAG, "otCommissionerStop: %s (%d)",
otThreadErrorToString(err), err);
}

err = otCommissionerStart(instance, commissioner_state_callback, NULL, NULL);
ESP_LOGI(TAG, "otCommissionerStart: %s (%d)",
otThreadErrorToString(err), err);

if (err == OT_ERROR_NONE) {
// Timeout = 600s (10 Minuten) - deckt exakt das Setup-Fenster ab,
// kein periodisches Nachtragen noetig
otCommissionerAddJoiner(instance, NULL, JOINER_PSKD, 600);
ESP_LOGI(TAG, "Open commissioning automatically for 10 minutes");
err = otCommissionerAddJoiner(instance, NULL, JOINER_PSKD, 600);
ESP_LOGI(TAG, "otCommissionerAddJoiner: %s (%d)",
otThreadErrorToString(err), err);

if (err == OT_ERROR_NONE)
{
ESP_LOGI(TAG,
"Open commissioning enabled for 600 seconds");
}
}
esp_openthread_lock_release();
}
Expand All @@ -46,15 +87,6 @@ static void button_task(void *arg)
bool was_pressed = false;

while (1) {
// uncomment for debug the button state
//
// static int64_t last_log = 0;
// int64_t now = esp_timer_get_time() / 1000;
// if (now - last_log > 1000) {
// ESP_LOGD(TAG, "GPIO0 state: %d", gpio_get_level(BUTTON_GPIO));
// last_log = now;
// }

bool pressed = (gpio_get_level(BUTTON_GPIO) == 0); // Active-Low

if (pressed && !was_pressed) {
Expand All @@ -72,12 +104,12 @@ static void button_task(void *arg)
}
was_pressed = pressed;

// Zeitfenster automatisch ablaufen lassen
// let the timeframe expire automatically
if (s_setup_mode_active) {
int64_t elapsed = (esp_timer_get_time() / 1000) - s_setup_mode_started_at;
if (elapsed > SETUP_WINDOW_MS) {
s_setup_mode_active = false;
ESP_LOGI(TAG, "Setup-Modus abgelaufen");
ESP_LOGI(TAG, "Setup-Modus is expired");
}
}

Expand Down