uint8_t channel; /*!< Channel of the AP */
} wifi_prov_config_set_data_t;
+/**
+ * @brief Type of context data passed to each get/set/apply handler
+ * function set in `wifi_prov_config_handlers` structure.
+ *
+ * This is passed as an opaque pointer, thereby allowing it be defined
+ * later in application code as per requirements.
+ */
+typedef struct wifi_prov_ctx wifi_prov_ctx_t;
+
/**
* @brief Internal handlers for receiving and responding to protocomm
* requests from master
* Handler function called when connection status
* of the slave (in WiFi station mode) is requested
*/
- esp_err_t (*get_status_handler)(wifi_prov_config_get_data_t *resp_data);
+ esp_err_t (*get_status_handler)(wifi_prov_config_get_data_t *resp_data,
+ wifi_prov_ctx_t **ctx);
/**
* Handler function called when WiFi connection configuration
* (eg. AP SSID, password, etc.) of the slave (in WiFi station mode)
* is to be set to user provided values
*/
- esp_err_t (*set_config_handler)(const wifi_prov_config_set_data_t *req_data);
+ esp_err_t (*set_config_handler)(const wifi_prov_config_set_data_t *req_data,
+ wifi_prov_ctx_t **ctx);
/**
* Handler function for applying the configuration that was set in
* updated connection status information when `get_status_handler` is
* invoked again by the master.
*/
- esp_err_t (*apply_config_handler)(void);
+ esp_err_t (*apply_config_handler)(wifi_prov_ctx_t **ctx);
+
+ /**
+ * Context pointer to be passed to above handler functions upon invocation
+ */
+ wifi_prov_ctx_t *ctx;
} wifi_prov_config_handlers_t;
/**
resp_get_status__init(resp_payload);
wifi_prov_config_get_data_t resp_data;
- if (h->get_status_handler(&resp_data) == ESP_OK) {
+ if (h->get_status_handler(&resp_data, &h->ctx) == ESP_OK) {
if (resp_data.wifi_state == WIFI_PROV_STA_CONNECTING) {
resp_payload->sta_state = WIFI_STATION_STATE__Connecting;
resp_payload->state_case = RESP_GET_STATUS__STATE_CONNECTED;
memcpy(req_data.bssid, req->cmd_set_config->bssid.data,
req->cmd_set_config->bssid.len);
req_data.channel = req->cmd_set_config->channel;
- if (h->set_config_handler(&req_data) == ESP_OK) {
+ if (h->set_config_handler(&req_data, &h->ctx) == ESP_OK) {
resp_payload->status = STATUS__Success;
}
resp_apply_config__init(resp_payload);
- if (h->apply_config_handler() == ESP_OK) {
+ if (h->apply_config_handler(&h->ctx) == ESP_OK) {
resp_payload->status = STATUS__Success;
} else {
resp_payload->status = STATUS__InvalidArgument;
Overview
--------
-This component provides protocomm endpoint handler - `wifi_prov_config_data_handler` - and related protobuf framework which can be used for Wi-Fi configuration in the context of device provisioning, though it may be used in non-provisioning cases as well. The configuration consists of three commands :
+This component provides protocomm endpoint handler - `wifi_prov_config_data_handler` - and related protobuf framework which can be used for Wi-Fi configuration in the context of device provisioning, though it may be used in non-provisioning cases as well.
+
+The configuration consists of three commands :
* `get_status` - For querying the Wi-Fi connection status
* `set_config` - For setting the Wi-Fi connection credentials
* `apply_config` - For applying the credentials saved during `set_config` and (re)start the Wi-Fi station
::
- esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
+ esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
{
/* Fill the wifi_prov_config_get_data_t structure
* with Wi-Fi station connection status information. */
return ESP_OK;
}
- esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
+ esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
{
/* Copy contents of req_data->ssid and req_data->password
* which are Wi-Fi AP credentials to which the device will connect */
return ESP_OK;
}
- esp_err_t apply_config_handler(void)
+ esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
{
/* Apply the Wi-Fi STA credentials saved during set_config */
.get_status_handler = get_status_handler,
.set_config_handler = set_config_handler,
.apply_config_handler = apply_config_handler,
+ .ctx = NULL
};
/* Set the endpoint handler */
-/* BLE based Provisioning Example
+/* SoftAP based Provisioning Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
static const char* TAG = "app_prov_handler";
-static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
+/* Provide definition of wifi_prov_ctx_t */
+struct wifi_prov_ctx {
+ wifi_config_t wifi_cfg;
+};
+
+static wifi_config_t *get_config(wifi_prov_ctx_t **ctx)
+{
+ return (*ctx ? &(*ctx)->wifi_cfg : NULL);
+}
+
+static wifi_config_t *new_config(wifi_prov_ctx_t **ctx)
+{
+ free(*ctx);
+ (*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t));
+ return get_config(ctx);
+}
+
+static void free_config(wifi_prov_ctx_t **ctx)
+{
+ free(*ctx);
+ *ctx = NULL;
+}
+
+static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
{
- /* Initialise to zero */
+ /* Initialize to zero */
memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t));
if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) {
return ESP_OK;
}
-static wifi_config_t *wifi_cfg;
-
-static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
+static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
{
+ wifi_config_t *wifi_cfg = get_config(ctx);
if (wifi_cfg) {
- free(wifi_cfg);
- wifi_cfg = NULL;
+ free_config(ctx);
}
- wifi_cfg = (wifi_config_t *) calloc(1, sizeof(wifi_config_t));
+ wifi_cfg = new_config(ctx);
if (!wifi_cfg) {
ESP_LOGE(TAG, "Unable to alloc wifi config");
return ESP_FAIL;
return ESP_OK;
}
-static esp_err_t apply_config_handler(void)
+static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
{
+ wifi_config_t *wifi_cfg = get_config(ctx);
if (!wifi_cfg) {
ESP_LOGE(TAG, "WiFi config not set");
return ESP_FAIL;
app_prov_configure_sta(wifi_cfg);
ESP_LOGI(TAG, "WiFi Credentials Applied");
- free(wifi_cfg);
- wifi_cfg = NULL;
+ free_config(ctx);
return ESP_OK;
}
.get_status_handler = get_status_handler,
.set_config_handler = set_config_handler,
.apply_config_handler = apply_config_handler,
+ .ctx = NULL
};
static const char* TAG = "app_prov_handler";
-static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
+/* Provide definition of wifi_prov_ctx_t */
+struct wifi_prov_ctx {
+ wifi_config_t wifi_cfg;
+};
+
+static wifi_config_t *get_config(wifi_prov_ctx_t **ctx)
+{
+ return (*ctx ? &(*ctx)->wifi_cfg : NULL);
+}
+
+static wifi_config_t *new_config(wifi_prov_ctx_t **ctx)
+{
+ free(*ctx);
+ (*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t));
+ return get_config(ctx);
+}
+
+static void free_config(wifi_prov_ctx_t **ctx)
+{
+ free(*ctx);
+ *ctx = NULL;
+}
+
+static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
{
- /* Initialise to zero */
+ /* Initialize to zero */
memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t));
if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) {
return ESP_OK;
}
-static wifi_config_t *wifi_cfg;
-
-static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
+static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
{
+ wifi_config_t *wifi_cfg = get_config(ctx);
if (wifi_cfg) {
- free(wifi_cfg);
- wifi_cfg = NULL;
+ free_config(ctx);
}
- wifi_cfg = (wifi_config_t *) calloc(1, sizeof(wifi_config_t));
+ wifi_cfg = new_config(ctx);
if (!wifi_cfg) {
ESP_LOGE(TAG, "Unable to alloc wifi config");
return ESP_FAIL;
return ESP_OK;
}
-static esp_err_t apply_config_handler(void)
+static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
{
+ wifi_config_t *wifi_cfg = get_config(ctx);
if (!wifi_cfg) {
ESP_LOGE(TAG, "WiFi config not set");
return ESP_FAIL;
app_prov_configure_sta(wifi_cfg);
ESP_LOGI(TAG, "WiFi Credentials Applied");
- free(wifi_cfg);
- wifi_cfg = NULL;
+ free_config(ctx);
return ESP_OK;
}
.get_status_handler = get_status_handler,
.set_config_handler = set_config_handler,
.apply_config_handler = apply_config_handler,
+ .ctx = NULL
};
static const char* TAG = "app_prov_handler";
+/* Provide definition of wifi_prov_ctx_t */
+struct wifi_prov_ctx {
+ wifi_config_t wifi_cfg;
+};
+
+static wifi_config_t *get_config(wifi_prov_ctx_t **ctx)
+{
+ return (*ctx ? &(*ctx)->wifi_cfg : NULL);
+}
+
+static wifi_config_t *new_config(wifi_prov_ctx_t **ctx)
+{
+ free(*ctx);
+ (*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t));
+ return get_config(ctx);
+}
+
+static void free_config(wifi_prov_ctx_t **ctx)
+{
+ free(*ctx);
+ *ctx = NULL;
+}
+
/****************** Handler for Custom Configuration *******************/
static esp_err_t custom_config_handler(const custom_config_t *config)
{
custom_prov_config_handler_t custom_prov_handler = custom_config_handler;
/****************** Handlers for Wi-Fi Configuration *******************/
-static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
+static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
{
- /* Initialise to zero */
+ /* Initialize to zero */
memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t));
if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) {
return ESP_OK;
}
-static wifi_config_t *wifi_cfg;
-
-static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
+static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
{
+ wifi_config_t *wifi_cfg = get_config(ctx);
if (wifi_cfg) {
- free(wifi_cfg);
- wifi_cfg = NULL;
+ free_config(ctx);
}
- wifi_cfg = (wifi_config_t *) calloc(1, sizeof(wifi_config_t));
+ wifi_cfg = new_config(ctx);
if (!wifi_cfg) {
ESP_LOGE(TAG, "Unable to alloc wifi config");
return ESP_FAIL;
return ESP_OK;
}
-static esp_err_t apply_config_handler(void)
+static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
{
+ wifi_config_t *wifi_cfg = get_config(ctx);
if (!wifi_cfg) {
ESP_LOGE(TAG, "WiFi config not set");
return ESP_FAIL;
app_prov_configure_sta(wifi_cfg);
ESP_LOGI(TAG, "WiFi Credentials Applied");
- free(wifi_cfg);
- wifi_cfg = NULL;
+ free_config(ctx);
return ESP_OK;
}
.get_status_handler = get_status_handler,
.set_config_handler = set_config_handler,
.apply_config_handler = apply_config_handler,
+ .ctx = NULL
};
static const char* TAG = "app_prov_handler";
-static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
+/* Provide definition of wifi_prov_ctx_t */
+struct wifi_prov_ctx {
+ wifi_config_t wifi_cfg;
+};
+
+static wifi_config_t *get_config(wifi_prov_ctx_t **ctx)
+{
+ return (*ctx ? &(*ctx)->wifi_cfg : NULL);
+}
+
+static wifi_config_t *new_config(wifi_prov_ctx_t **ctx)
+{
+ free(*ctx);
+ (*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t));
+ return get_config(ctx);
+}
+
+static void free_config(wifi_prov_ctx_t **ctx)
+{
+ free(*ctx);
+ *ctx = NULL;
+}
+
+static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
{
- /* Initialise to zero */
+ /* Initialize to zero */
memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t));
if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) {
return ESP_OK;
}
-static wifi_config_t *wifi_cfg;
-
-static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
+static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
{
+ wifi_config_t *wifi_cfg = get_config(ctx);
if (wifi_cfg) {
- free(wifi_cfg);
- wifi_cfg = NULL;
+ free_config(ctx);
}
- wifi_cfg = (wifi_config_t *) calloc(1, sizeof(wifi_config_t));
+ wifi_cfg = new_config(ctx);
if (!wifi_cfg) {
ESP_LOGE(TAG, "Unable to alloc wifi config");
return ESP_FAIL;
return ESP_OK;
}
-static esp_err_t apply_config_handler(void)
+static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
{
+ wifi_config_t *wifi_cfg = get_config(ctx);
if (!wifi_cfg) {
ESP_LOGE(TAG, "WiFi config not set");
return ESP_FAIL;
app_prov_configure_sta(wifi_cfg);
ESP_LOGI(TAG, "WiFi Credentials Applied");
- free(wifi_cfg);
- wifi_cfg = NULL;
+ free_config(ctx);
return ESP_OK;
}
.get_status_handler = get_status_handler,
.set_config_handler = set_config_handler,
.apply_config_handler = apply_config_handler,
+ .ctx = NULL
};