mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-30 19:19:21 +00:00
wifi_provisioning: added wifi-ctrl reset endpoint
This commit is contained in:
@@ -1,16 +1,8 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -22,6 +14,7 @@
|
||||
|
||||
#include "wifi_provisioning/wifi_config.h"
|
||||
#include "wifi_provisioning/wifi_scan.h"
|
||||
#include "wifi_ctrl.h"
|
||||
#include "wifi_provisioning/manager.h"
|
||||
#include "wifi_provisioning_priv.h"
|
||||
|
||||
@@ -202,3 +195,19 @@ esp_err_t get_wifi_scan_handlers(wifi_prov_scan_handlers_t *ptr)
|
||||
ptr->ctx = NULL;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static esp_err_t ctrl_reset(void)
|
||||
{
|
||||
return wifi_prov_mgr_reset_sm_state_on_failure();
|
||||
}
|
||||
|
||||
esp_err_t get_wifi_ctrl_handlers(wifi_ctrl_handlers_t *ptr)
|
||||
{
|
||||
if (!ptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ptr->ctrl_reset = ctrl_reset;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@@ -112,6 +112,9 @@ struct wifi_prov_mgr_ctx {
|
||||
/* Protocomm handlers for Wi-Fi scan endpoint */
|
||||
wifi_prov_scan_handlers_t *wifi_scan_handlers;
|
||||
|
||||
/* Protocomm handlers for Wi-Fi ctrl endpoint */
|
||||
wifi_ctrl_handlers_t *wifi_ctrl_handlers;
|
||||
|
||||
/* Count of used endpoint UUIDs */
|
||||
unsigned int endpoint_uuid_used;
|
||||
|
||||
@@ -386,12 +389,36 @@ static esp_err_t wifi_prov_mgr_start_service(const char *service_name, const cha
|
||||
return ret;
|
||||
}
|
||||
|
||||
prov_ctx->wifi_ctrl_handlers = malloc(sizeof(wifi_ctrl_handlers_t));
|
||||
ret = get_wifi_ctrl_handlers(prov_ctx->wifi_ctrl_handlers);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for Wi-Fi ctrl handlers");
|
||||
free(prov_ctx->wifi_prov_handlers);
|
||||
scheme->prov_stop(prov_ctx->pc);
|
||||
protocomm_delete(prov_ctx->pc);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Add endpoint for controlling state of Wi-Fi station */
|
||||
ret = protocomm_add_endpoint(prov_ctx->pc, "prov-ctrl",
|
||||
wifi_ctrl_handler,
|
||||
prov_ctx->wifi_ctrl_handlers);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set Wi-Fi ctrl endpoint");
|
||||
free(prov_ctx->wifi_ctrl_handlers);
|
||||
free(prov_ctx->wifi_prov_handlers);
|
||||
scheme->prov_stop(prov_ctx->pc);
|
||||
protocomm_delete(prov_ctx->pc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Register global event handler */
|
||||
ret = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID,
|
||||
wifi_prov_mgr_event_handler_internal, NULL);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to register WiFi event handler");
|
||||
free(prov_ctx->wifi_scan_handlers);
|
||||
free(prov_ctx->wifi_ctrl_handlers);
|
||||
free(prov_ctx->wifi_prov_handlers);
|
||||
scheme->prov_stop(prov_ctx->pc);
|
||||
protocomm_delete(prov_ctx->pc);
|
||||
@@ -405,6 +432,7 @@ static esp_err_t wifi_prov_mgr_start_service(const char *service_name, const cha
|
||||
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID,
|
||||
wifi_prov_mgr_event_handler_internal);
|
||||
free(prov_ctx->wifi_scan_handlers);
|
||||
free(prov_ctx->wifi_ctrl_handlers);
|
||||
free(prov_ctx->wifi_prov_handlers);
|
||||
scheme->prov_stop(prov_ctx->pc);
|
||||
protocomm_delete(prov_ctx->pc);
|
||||
@@ -512,6 +540,9 @@ static void prov_stop_task(void *arg)
|
||||
free(prov_ctx->wifi_scan_handlers);
|
||||
prov_ctx->wifi_scan_handlers = NULL;
|
||||
|
||||
free(prov_ctx->wifi_ctrl_handlers);
|
||||
prov_ctx->wifi_ctrl_handlers = NULL;
|
||||
|
||||
/* Switch device to Wi-Fi STA mode irrespective of
|
||||
* whether provisioning was completed or not */
|
||||
esp_wifi_set_mode(WIFI_MODE_STA);
|
||||
@@ -1262,6 +1293,12 @@ esp_err_t wifi_prov_mgr_init(wifi_prov_mgr_config_t config)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = scheme->set_config_endpoint(prov_ctx->prov_scheme_config, "prov-ctrl", 0xFF4F);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to configure Wi-Fi state control endpoint");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = scheme->set_config_endpoint(prov_ctx->prov_scheme_config, "prov-scan", 0xFF50);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to configure Wi-Fi scanning endpoint");
|
||||
|
147
components/wifi_provisioning/src/wifi_ctrl.c
Normal file
147
components/wifi_provisioning/src/wifi_ctrl.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <esp_log.h>
|
||||
#include <string.h>
|
||||
#include <esp_err.h>
|
||||
|
||||
#include "wifi_ctrl.pb-c.h"
|
||||
|
||||
#include "wifi_ctrl.h"
|
||||
|
||||
static const char *TAG = "proto_wifi_ctrl";
|
||||
|
||||
typedef struct wifi_ctrl_cmd {
|
||||
int cmd_id;
|
||||
esp_err_t (*command_handler)(WiFiCtrlPayload *req,
|
||||
WiFiCtrlPayload *resp, void *priv_data);
|
||||
} wifi_ctrl_cmd_t;
|
||||
|
||||
static esp_err_t cmd_ctrl_reset_handler(WiFiCtrlPayload *req,
|
||||
WiFiCtrlPayload *resp,
|
||||
void *priv_data);
|
||||
|
||||
static wifi_ctrl_cmd_t cmd_table[] = {
|
||||
{
|
||||
.cmd_id = WI_FI_CTRL_MSG_TYPE__TypeCmdCtrlReset,
|
||||
.command_handler = cmd_ctrl_reset_handler
|
||||
},
|
||||
};
|
||||
|
||||
static esp_err_t cmd_ctrl_reset_handler(WiFiCtrlPayload *req,
|
||||
WiFiCtrlPayload *resp, void *priv_data)
|
||||
{
|
||||
wifi_ctrl_handlers_t *h = (wifi_ctrl_handlers_t *) priv_data;
|
||||
if (!h) {
|
||||
ESP_LOGE(TAG, "Command invoked without handlers");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
RespCtrlReset *resp_payload = (RespCtrlReset *) malloc(sizeof(RespCtrlReset));
|
||||
if (!resp_payload) {
|
||||
ESP_LOGE(TAG, "Error allocating memory");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
resp_ctrl_reset__init(resp_payload);
|
||||
resp->status = (h->ctrl_reset() == ESP_OK ?
|
||||
STATUS__Success : STATUS__InternalError);
|
||||
resp->payload_case = WI_FI_CTRL_PAYLOAD__PAYLOAD_RESP_CTRL_RESET;
|
||||
resp->resp_ctrl_reset = resp_payload;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static int lookup_cmd_handler(int cmd_id)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(cmd_table)/sizeof(wifi_ctrl_cmd_t); i++) {
|
||||
if (cmd_table[i].cmd_id == cmd_id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void wifi_ctrl_cmd_cleanup(WiFiCtrlPayload *resp, void *priv_data)
|
||||
{
|
||||
switch (resp->msg) {
|
||||
case WI_FI_CTRL_MSG_TYPE__TypeRespCtrlReset:
|
||||
{
|
||||
free(resp->resp_ctrl_reset);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unsupported response type in cleanup_handler");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static esp_err_t wifi_ctrl_cmd_dispatcher(WiFiCtrlPayload *req,
|
||||
WiFiCtrlPayload *resp, void *priv_data)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
ESP_LOGD(TAG, "In wifi_ctrl_cmd_dispatcher Cmd=%d", req->msg);
|
||||
|
||||
int cmd_index = lookup_cmd_handler(req->msg);
|
||||
if (cmd_index < 0) {
|
||||
ESP_LOGE(TAG, "Failed to find cmd with ID = %d in the command table", req->msg);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ret = cmd_table[cmd_index].command_handler(req, resp, priv_data);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error executing command handler");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t wifi_ctrl_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen, void *priv_data)
|
||||
{
|
||||
WiFiCtrlPayload *req;
|
||||
WiFiCtrlPayload resp;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
req = wi_fi_ctrl_payload__unpack(NULL, inlen, inbuf);
|
||||
if (!req) {
|
||||
ESP_LOGE(TAG, "Unable to unpack ctrl message");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
wi_fi_ctrl_payload__init(&resp);
|
||||
ret = wifi_ctrl_cmd_dispatcher(req, &resp, priv_data);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Command dispatcher error %02X", ret);
|
||||
ret = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
resp.msg = req->msg + 1; /* Response is request + 1 */
|
||||
*outlen = wi_fi_ctrl_payload__get_packed_size(&resp);
|
||||
if (*outlen <= 0) {
|
||||
ESP_LOGE(TAG, "Invalid encoding for response");
|
||||
ret = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*outbuf = (uint8_t *) malloc(*outlen);
|
||||
if (!*outbuf) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for the output buffer");
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
goto exit;
|
||||
}
|
||||
wi_fi_ctrl_payload__pack(&resp, *outbuf);
|
||||
ESP_LOGD(TAG, "Response packet size : %d", *outlen);
|
||||
exit:
|
||||
|
||||
wi_fi_ctrl_payload__free_unpacked(req, NULL);
|
||||
wifi_ctrl_cmd_cleanup(&resp, priv_data);
|
||||
return ret;
|
||||
}
|
47
components/wifi_provisioning/src/wifi_ctrl.h
Normal file
47
components/wifi_provisioning/src/wifi_ctrl.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _PROV_WIFI_CTRL_H_
|
||||
#define _PROV_WIFI_CTRL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Internal handlers for receiving and responding to protocomm
|
||||
* requests from client
|
||||
*
|
||||
* This is to be passed as priv_data for protocomm request handler
|
||||
* (refer to `wifi_ctrl_handler()`) when calling `protocomm_add_endpoint()`.
|
||||
*/
|
||||
typedef struct wifi_ctrl_handlers {
|
||||
/**
|
||||
* Handler function called when ctrl reset command is received
|
||||
*/
|
||||
esp_err_t (*ctrl_reset)(void);
|
||||
|
||||
/**
|
||||
* Handler function called when ctrl reprov command is received
|
||||
*/
|
||||
esp_err_t (*ctrl_reprov)(void);
|
||||
|
||||
} wifi_ctrl_handlers_t;
|
||||
|
||||
/**
|
||||
* @brief Handler for sending on demand Wi-Fi ctrl results
|
||||
*
|
||||
* This is to be registered as the `prov-ctrl` endpoint handler
|
||||
* (protocomm `protocomm_req_handler_t`) using `protocomm_add_endpoint()`
|
||||
*/
|
||||
esp_err_t wifi_ctrl_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen, void *priv_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1,16 +1,8 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -20,6 +12,7 @@
|
||||
#include "wifi_provisioning/manager.h"
|
||||
#include "wifi_provisioning/wifi_config.h"
|
||||
#include "wifi_provisioning/wifi_scan.h"
|
||||
#include "wifi_ctrl.h"
|
||||
|
||||
/**
|
||||
* @brief Notify manager that provisioning is done
|
||||
@@ -100,3 +93,14 @@ esp_err_t get_wifi_prov_handlers(wifi_prov_config_handlers_t *ptr);
|
||||
* - ESP_ERR_INVALID_ARG : null argument
|
||||
*/
|
||||
esp_err_t get_wifi_scan_handlers(wifi_prov_scan_handlers_t *ptr);
|
||||
|
||||
/**
|
||||
* @brief Get protocomm handlers for wifi_ctrl provisioning endpoint
|
||||
*
|
||||
* @param[in] ptr pointer to structure to be set
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - ESP_ERR_INVALID_ARG : null argument
|
||||
*/
|
||||
esp_err_t get_wifi_ctrl_handlers(wifi_ctrl_handlers_t *ptr);
|
||||
|
Reference in New Issue
Block a user