diff --git a/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h b/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h index 2a39e0e935..4058540adb 100644 --- a/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h +++ b/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h @@ -81,6 +81,15 @@ typedef struct { 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 @@ -93,14 +102,16 @@ typedef struct wifi_prov_config_handlers { * 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 @@ -109,7 +120,12 @@ typedef struct wifi_prov_config_handlers { * 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; /** diff --git a/components/wifi_provisioning/src/wifi_config.c b/components/wifi_provisioning/src/wifi_config.c index 6ce1798a7f..09ccc37d53 100644 --- a/components/wifi_provisioning/src/wifi_config.c +++ b/components/wifi_provisioning/src/wifi_config.c @@ -72,7 +72,7 @@ static esp_err_t cmd_get_status_handler(WiFiConfigPayload *req, 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; @@ -158,7 +158,7 @@ static esp_err_t cmd_set_config_handler(WiFiConfigPayload *req, 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; } @@ -185,7 +185,7 @@ static esp_err_t cmd_apply_config_handler(WiFiConfigPayload *req, 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; diff --git a/docs/en/api-reference/provisioning/wifi_provisioning.rst b/docs/en/api-reference/provisioning/wifi_provisioning.rst index a822bf62ff..7f78ee5830 100644 --- a/docs/en/api-reference/provisioning/wifi_provisioning.rst +++ b/docs/en/api-reference/provisioning/wifi_provisioning.rst @@ -4,7 +4,9 @@ Wi-Fi Provisioning 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 @@ -18,7 +20,7 @@ Application Example :: - 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. */ @@ -26,7 +28,7 @@ Application Example 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 */ @@ -34,7 +36,7 @@ Application Example 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 */ @@ -47,6 +49,7 @@ Application Example .get_status_handler = get_status_handler, .set_config_handler = set_config_handler, .apply_config_handler = apply_config_handler, + .ctx = NULL }; /* Set the endpoint handler */ diff --git a/examples/provisioning/ble_prov/main/app_prov_handlers.c b/examples/provisioning/ble_prov/main/app_prov_handlers.c index ca67269490..4a0c0d99a7 100644 --- a/examples/provisioning/ble_prov/main/app_prov_handlers.c +++ b/examples/provisioning/ble_prov/main/app_prov_handlers.c @@ -1,4 +1,4 @@ -/* BLE based Provisioning Example +/* SoftAP based Provisioning Example This example code is in the Public Domain (or CC0 licensed, at your option.) @@ -23,9 +23,32 @@ 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) { - /* Initialise to zero */ + 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) +{ + /* 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) { @@ -60,16 +83,14 @@ static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data) 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; @@ -84,8 +105,9 @@ static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data) 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; @@ -94,8 +116,7 @@ static esp_err_t apply_config_handler(void) app_prov_configure_sta(wifi_cfg); ESP_LOGI(TAG, "WiFi Credentials Applied"); - free(wifi_cfg); - wifi_cfg = NULL; + free_config(ctx); return ESP_OK; } @@ -103,4 +124,5 @@ wifi_prov_config_handlers_t wifi_prov_handlers = { .get_status_handler = get_status_handler, .set_config_handler = set_config_handler, .apply_config_handler = apply_config_handler, + .ctx = NULL }; diff --git a/examples/provisioning/console_prov/main/app_prov_handlers.c b/examples/provisioning/console_prov/main/app_prov_handlers.c index 55d2f2c192..49c29739f8 100644 --- a/examples/provisioning/console_prov/main/app_prov_handlers.c +++ b/examples/provisioning/console_prov/main/app_prov_handlers.c @@ -23,9 +23,32 @@ 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) { - /* Initialise to zero */ + 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) +{ + /* 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) { @@ -60,16 +83,14 @@ static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data) 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; @@ -84,8 +105,9 @@ static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data) 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; @@ -94,8 +116,7 @@ static esp_err_t apply_config_handler(void) app_prov_configure_sta(wifi_cfg); ESP_LOGI(TAG, "WiFi Credentials Applied"); - free(wifi_cfg); - wifi_cfg = NULL; + free_config(ctx); return ESP_OK; } @@ -103,4 +124,5 @@ wifi_prov_config_handlers_t wifi_prov_handlers = { .get_status_handler = get_status_handler, .set_config_handler = set_config_handler, .apply_config_handler = apply_config_handler, + .ctx = NULL }; diff --git a/examples/provisioning/custom_config/main/app_prov_handlers.c b/examples/provisioning/custom_config/main/app_prov_handlers.c index 14dec260bb..c67eeebca4 100644 --- a/examples/provisioning/custom_config/main/app_prov_handlers.c +++ b/examples/provisioning/custom_config/main/app_prov_handlers.c @@ -24,6 +24,29 @@ 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) { @@ -35,9 +58,9 @@ 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) { @@ -72,16 +95,14 @@ static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data) 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; @@ -96,8 +117,9 @@ static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data) 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; @@ -106,8 +128,7 @@ static esp_err_t apply_config_handler(void) app_prov_configure_sta(wifi_cfg); ESP_LOGI(TAG, "WiFi Credentials Applied"); - free(wifi_cfg); - wifi_cfg = NULL; + free_config(ctx); return ESP_OK; } @@ -115,4 +136,5 @@ wifi_prov_config_handlers_t wifi_prov_handlers = { .get_status_handler = get_status_handler, .set_config_handler = set_config_handler, .apply_config_handler = apply_config_handler, + .ctx = NULL }; diff --git a/examples/provisioning/softap_prov/main/app_prov_handlers.c b/examples/provisioning/softap_prov/main/app_prov_handlers.c index c9704576c7..4a0c0d99a7 100644 --- a/examples/provisioning/softap_prov/main/app_prov_handlers.c +++ b/examples/provisioning/softap_prov/main/app_prov_handlers.c @@ -23,9 +23,32 @@ 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) { - /* Initialise to zero */ + 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) +{ + /* 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) { @@ -60,16 +83,14 @@ static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data) 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; @@ -84,8 +105,9 @@ static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data) 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; @@ -94,8 +116,7 @@ static esp_err_t apply_config_handler(void) app_prov_configure_sta(wifi_cfg); ESP_LOGI(TAG, "WiFi Credentials Applied"); - free(wifi_cfg); - wifi_cfg = NULL; + free_config(ctx); return ESP_OK; } @@ -103,4 +124,5 @@ wifi_prov_config_handlers_t wifi_prov_handlers = { .get_status_handler = get_status_handler, .set_config_handler = set_config_handler, .apply_config_handler = apply_config_handler, + .ctx = NULL };