From 68962223327ebd3d6cd73f04ab48dd38c25fb92d Mon Sep 17 00:00:00 2001 From: Wolfgang Hottgenroth Date: Tue, 9 Mar 2021 14:27:15 +0100 Subject: [PATCH] changes --- src/main/app_main.c | 255 ++-------------------------------------- src/main/network_mngr.c | 244 ++++++++++++++++++++++++++++++++++++++ src/main/network_mngr.h | 10 ++ tools/startBuildEnv.sh | 0 4 files changed, 262 insertions(+), 247 deletions(-) create mode 100644 src/main/network_mngr.c create mode 100644 src/main/network_mngr.h mode change 100644 => 100755 tools/startBuildEnv.sh diff --git a/src/main/app_main.c b/src/main/app_main.c index 4180731..3573cc5 100644 --- a/src/main/app_main.c +++ b/src/main/app_main.c @@ -1,15 +1,9 @@ -/* Wi-Fi Provisioning Manager Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ #include #include +#include "network_mngr.h" + #include #include #include @@ -19,109 +13,9 @@ #include #include -#include -#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_BLE -#include -#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_BLE */ -#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP -#include -#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP */ - -static const char *TAG = "app"; - -/* Signal Wi-Fi events on this event-group */ -const int WIFI_CONNECTED_EVENT = BIT0; -static EventGroupHandle_t wifi_event_group; - -/* Event handler for catching system events */ -static void event_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - if (event_base == WIFI_PROV_EVENT) { - switch (event_id) { - case WIFI_PROV_START: - ESP_LOGI(TAG, "Provisioning started"); - break; - case WIFI_PROV_CRED_RECV: { - wifi_sta_config_t *wifi_sta_cfg = (wifi_sta_config_t *)event_data; - ESP_LOGI(TAG, "Received Wi-Fi credentials" - "\n\tSSID : %s\n\tPassword : %s", - (const char *) wifi_sta_cfg->ssid, - (const char *) wifi_sta_cfg->password); - break; - } - case WIFI_PROV_CRED_FAIL: { - wifi_prov_sta_fail_reason_t *reason = (wifi_prov_sta_fail_reason_t *)event_data; - ESP_LOGE(TAG, "Provisioning failed!\n\tReason : %s" - "\n\tPlease reset to factory and retry provisioning", - (*reason == WIFI_PROV_STA_AUTH_ERROR) ? - "Wi-Fi station authentication failed" : "Wi-Fi access-point not found"); - break; - } - case WIFI_PROV_CRED_SUCCESS: - ESP_LOGI(TAG, "Provisioning successful"); - break; - case WIFI_PROV_END: - /* De-initialize manager once provisioning is finished */ - wifi_prov_mgr_deinit(); - break; - default: - break; - } - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - esp_wifi_connect(); - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; - ESP_LOGI(TAG, "Connected with IP Address:" IPSTR, IP2STR(&event->ip_info.ip)); - /* Signal main application to continue execution */ - xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_EVENT); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - ESP_LOGI(TAG, "Disconnected. Connecting to the AP again..."); - esp_wifi_connect(); - } -} - -static void wifi_init_sta(void) -{ - /* Start Wi-Fi in station mode */ - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static void get_device_service_name(char *service_name, size_t max) -{ - uint8_t eth_mac[6]; - const char *ssid_prefix = "PROV_"; - esp_wifi_get_mac(WIFI_IF_STA, eth_mac); - snprintf(service_name, max, "%s%02X%02X%02X", - ssid_prefix, eth_mac[3], eth_mac[4], eth_mac[5]); -} - -/* Handler for the optional provisioning endpoint registered by the application. - * The data format can be chosen by applications. Here, we are using plain ascii text. - * Applications can choose to use other formats like protobuf, JSON, XML, etc. - */ -esp_err_t custom_prov_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, - uint8_t **outbuf, ssize_t *outlen, void *priv_data) -{ - if (inbuf) { - ESP_LOGI(TAG, "Received data: %.*s", inlen, (char *)inbuf); - } - char response[] = "SUCCESS"; - *outbuf = (uint8_t *)strdup(response); - if (*outbuf == NULL) { - ESP_LOGE(TAG, "System out of memory"); - return ESP_ERR_NO_MEM; - } - *outlen = strlen(response) + 1; /* +1 for NULL terminating byte */ - - return ESP_OK; -} - -void app_main(void) -{ +void deviceInit() { /* Initialize NVS partition */ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { @@ -132,147 +26,14 @@ void app_main(void) /* Retry nvs_flash_init */ ESP_ERROR_CHECK(nvs_flash_init()); } +} - /* Initialize TCP/IP */ - ESP_ERROR_CHECK(esp_netif_init()); +void app_main(void) +{ + deviceInit(); - /* Initialize the event loop */ - ESP_ERROR_CHECK(esp_event_loop_create_default()); - wifi_event_group = xEventGroupCreate(); + networkInit(false); - /* Register our event handler for Wi-Fi, IP and Provisioning related events */ - ESP_ERROR_CHECK(esp_event_handler_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); - ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); - - /* Initialize Wi-Fi including netif with default config */ - esp_netif_create_default_wifi_sta(); -#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP - esp_netif_create_default_wifi_ap(); -#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP */ - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - - /* Configuration for the provisioning manager */ - wifi_prov_mgr_config_t config = { - /* What is the Provisioning Scheme that we want ? - * wifi_prov_scheme_softap or wifi_prov_scheme_ble */ -#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_BLE - .scheme = wifi_prov_scheme_ble, -#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_BLE */ -#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP - .scheme = wifi_prov_scheme_softap, -#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP */ - - /* Any default scheme specific event handler that you would - * like to choose. Since our example application requires - * neither BT nor BLE, we can choose to release the associated - * memory once provisioning is complete, or not needed - * (in case when device is already provisioned). Choosing - * appropriate scheme specific event handler allows the manager - * to take care of this automatically. This can be set to - * WIFI_PROV_EVENT_HANDLER_NONE when using wifi_prov_scheme_softap*/ -#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_BLE - .scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM -#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_BLE */ -#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP - .scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE -#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP */ - }; - - /* Initialize provisioning manager with the - * configuration parameters set above */ - ESP_ERROR_CHECK(wifi_prov_mgr_init(config)); - - bool provisioned = false; - /* Let's find out if the device is provisioned */ - ESP_ERROR_CHECK(wifi_prov_mgr_is_provisioned(&provisioned)); - - /* If device is not yet provisioned start provisioning service */ - if (!provisioned) { - ESP_LOGI(TAG, "Starting provisioning"); - - /* What is the Device Service Name that we want - * This translates to : - * - Wi-Fi SSID when scheme is wifi_prov_scheme_softap - * - device name when scheme is wifi_prov_scheme_ble - */ - char service_name[12]; - get_device_service_name(service_name, sizeof(service_name)); - - /* What is the security level that we want (0 or 1): - * - WIFI_PROV_SECURITY_0 is simply plain text communication. - * - WIFI_PROV_SECURITY_1 is secure communication which consists of secure handshake - * using X25519 key exchange and proof of possession (pop) and AES-CTR - * for encryption/decryption of messages. - */ - wifi_prov_security_t security = WIFI_PROV_SECURITY_1; - - /* Do we want a proof-of-possession (ignored if Security 0 is selected): - * - this should be a string with length > 0 - * - NULL if not used - */ - const char *pop = "abcd1234"; - - /* What is the service key (could be NULL) - * This translates to : - * - Wi-Fi password when scheme is wifi_prov_scheme_softap - * - simply ignored when scheme is wifi_prov_scheme_ble - */ - const char *service_key = NULL; - -#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_BLE - /* This step is only useful when scheme is wifi_prov_scheme_ble. This will - * set a custom 128 bit UUID which will be included in the BLE advertisement - * and will correspond to the primary GATT service that provides provisioning - * endpoints as GATT characteristics. Each GATT characteristic will be - * formed using the primary service UUID as base, with different auto assigned - * 12th and 13th bytes (assume counting starts from 0th byte). The client side - * applications must identify the endpoints by reading the User Characteristic - * Description descriptor (0x2901) for each characteristic, which contains the - * endpoint name of the characteristic */ - uint8_t custom_service_uuid[] = { - /* LSB <--------------------------------------- - * ---------------------------------------> MSB */ - 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf, - 0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02, - }; - wifi_prov_scheme_ble_set_service_uuid(custom_service_uuid); -#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_BLE */ - - /* An optional endpoint that applications can create if they expect to - * get some additional custom data during provisioning workflow. - * The endpoint name can be anything of your choice. - * This call must be made before starting the provisioning. - */ - wifi_prov_mgr_endpoint_create("custom-data"); - /* Start provisioning service */ - ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning(security, pop, service_name, service_key)); - - /* The handler for the optional endpoint created above. - * This call must be made after starting the provisioning, and only if the endpoint - * has already been created above. - */ - wifi_prov_mgr_endpoint_register("custom-data", custom_prov_data_handler, NULL); - - /* Uncomment the following to wait for the provisioning to finish and then release - * the resources of the manager. Since in this case de-initialization is triggered - * by the default event loop handler, we don't need to call the following */ - // wifi_prov_mgr_wait(); - // wifi_prov_mgr_deinit(); - } else { - ESP_LOGI(TAG, "Already provisioned, starting Wi-Fi STA"); - - /* We don't need the manager as device is already provisioned, - * so let's release it's resources */ - wifi_prov_mgr_deinit(); - - /* Start Wi-Fi station */ - wifi_init_sta(); - } - - /* Wait for Wi-Fi connection */ - xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_EVENT, false, true, portMAX_DELAY); /* Start main application now */ while (1) { diff --git a/src/main/network_mngr.c b/src/main/network_mngr.c new file mode 100644 index 0000000..18db7ec --- /dev/null +++ b/src/main/network_mngr.c @@ -0,0 +1,244 @@ +/* + + Taken from + Wi-Fi Provisioning Manager Example + of ESP-IDF 4.3 + +*/ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +static const char *TAG = "app"; + +/* Signal Wi-Fi events on this event-group */ +const int WIFI_CONNECTED_EVENT = BIT0; +static EventGroupHandle_t wifi_event_group; + +/* Event handler for catching system events */ +static void event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + if (event_base == WIFI_PROV_EVENT) { + switch (event_id) { + case WIFI_PROV_START: + ESP_LOGI(TAG, "Provisioning started"); + break; + case WIFI_PROV_CRED_RECV: { + wifi_sta_config_t *wifi_sta_cfg = (wifi_sta_config_t *)event_data; + ESP_LOGI(TAG, "Received Wi-Fi credentials" + "\n\tSSID : %s\n\tPassword : %s", + (const char *) wifi_sta_cfg->ssid, + (const char *) wifi_sta_cfg->password); + break; + } + case WIFI_PROV_CRED_FAIL: { + wifi_prov_sta_fail_reason_t *reason = (wifi_prov_sta_fail_reason_t *)event_data; + ESP_LOGE(TAG, "Provisioning failed!\n\tReason : %s" + "\n\tPlease reset to factory and retry provisioning", + (*reason == WIFI_PROV_STA_AUTH_ERROR) ? + "Wi-Fi station authentication failed" : "Wi-Fi access-point not found"); + break; + } + case WIFI_PROV_CRED_SUCCESS: + ESP_LOGI(TAG, "Provisioning successful"); + break; + case WIFI_PROV_END: + /* De-initialize manager once provisioning is finished */ + wifi_prov_mgr_deinit(); + break; + default: + break; + } + } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + esp_wifi_connect(); + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + ESP_LOGI(TAG, "Connected with IP Address:" IPSTR, IP2STR(&event->ip_info.ip)); + /* Signal main application to continue execution */ + xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_EVENT); + } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + ESP_LOGI(TAG, "Disconnected. Connecting to the AP again..."); + esp_wifi_connect(); + } +} + +static void wifi_init_sta(void) +{ + /* Start Wi-Fi in station mode */ + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + +static void get_device_service_name(char *service_name, size_t max) +{ + uint8_t eth_mac[6]; + const char *ssid_prefix = "PROV_"; + esp_wifi_get_mac(WIFI_IF_STA, eth_mac); + snprintf(service_name, max, "%s%02X%02X%02X", + ssid_prefix, eth_mac[3], eth_mac[4], eth_mac[5]); +} + +/* Handler for the optional provisioning endpoint registered by the application. + * The data format can be chosen by applications. Here, we are using plain ascii text. + * Applications can choose to use other formats like protobuf, JSON, XML, etc. + */ +esp_err_t custom_prov_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, + uint8_t **outbuf, ssize_t *outlen, void *priv_data) +{ + if (inbuf) { + ESP_LOGI(TAG, "Received data: %.*s", inlen, (char *)inbuf); + } + char response[] = "SUCCESS"; + *outbuf = (uint8_t *)strdup(response); + if (*outbuf == NULL) { + ESP_LOGE(TAG, "System out of memory"); + return ESP_ERR_NO_MEM; + } + *outlen = strlen(response) + 1; /* +1 for NULL terminating byte */ + + return ESP_OK; +} + +void networkInit(bool forceProv) +{ + /* Initialize TCP/IP */ + ESP_ERROR_CHECK(esp_netif_init()); + + /* Initialize the event loop */ + ESP_ERROR_CHECK(esp_event_loop_create_default()); + wifi_event_group = xEventGroupCreate(); + + /* Register our event handler for Wi-Fi, IP and Provisioning related events */ + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); + + /* Initialize Wi-Fi including netif with default config */ + esp_netif_create_default_wifi_sta(); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + /* Configuration for the provisioning manager */ + wifi_prov_mgr_config_t config = { + /* What is the Provisioning Scheme that we want ? + * wifi_prov_scheme_softap or wifi_prov_scheme_ble */ + .scheme = wifi_prov_scheme_ble, + + /* Any default scheme specific event handler that you would + * like to choose. Since our example application requires + * neither BT nor BLE, we can choose to release the associated + * memory once provisioning is complete, or not needed + * (in case when device is already provisioned). Choosing + * appropriate scheme specific event handler allows the manager + * to take care of this automatically. This can be set to + * WIFI_PROV_EVENT_HANDLER_NONE when using wifi_prov_scheme_softap*/ + .scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM + }; + + /* Initialize provisioning manager with the + * configuration parameters set above */ + ESP_ERROR_CHECK(wifi_prov_mgr_init(config)); + + bool provisioned = false; + /* Let's find out if the device is provisioned */ + ESP_ERROR_CHECK(wifi_prov_mgr_is_provisioned(&provisioned)); + + /* If device is not yet provisioned start provisioning service */ + if (forceProv || !provisioned) { + ESP_LOGI(TAG, "Starting provisioning"); + + /* What is the Device Service Name that we want + * This translates to : + * - Wi-Fi SSID when scheme is wifi_prov_scheme_softap + * - device name when scheme is wifi_prov_scheme_ble + */ + char service_name[12]; + get_device_service_name(service_name, sizeof(service_name)); + + /* What is the security level that we want (0 or 1): + * - WIFI_PROV_SECURITY_0 is simply plain text communication. + * - WIFI_PROV_SECURITY_1 is secure communication which consists of secure handshake + * using X25519 key exchange and proof of possession (pop) and AES-CTR + * for encryption/decryption of messages. + */ + wifi_prov_security_t security = WIFI_PROV_SECURITY_1; + + /* Do we want a proof-of-possession (ignored if Security 0 is selected): + * - this should be a string with length > 0 + * - NULL if not used + */ + const char *pop = "abcd1234"; + + /* What is the service key (could be NULL) + * This translates to : + * - Wi-Fi password when scheme is wifi_prov_scheme_softap + * - simply ignored when scheme is wifi_prov_scheme_ble + */ + const char *service_key = NULL; + + /* This step is only useful when scheme is wifi_prov_scheme_ble. This will + * set a custom 128 bit UUID which will be included in the BLE advertisement + * and will correspond to the primary GATT service that provides provisioning + * endpoints as GATT characteristics. Each GATT characteristic will be + * formed using the primary service UUID as base, with different auto assigned + * 12th and 13th bytes (assume counting starts from 0th byte). The client side + * applications must identify the endpoints by reading the User Characteristic + * Description descriptor (0x2901) for each characteristic, which contains the + * endpoint name of the characteristic */ + uint8_t custom_service_uuid[] = { + /* LSB <--------------------------------------- + * ---------------------------------------> MSB */ + 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf, + 0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02, + }; + wifi_prov_scheme_ble_set_service_uuid(custom_service_uuid); + + /* An optional endpoint that applications can create if they expect to + * get some additional custom data during provisioning workflow. + * The endpoint name can be anything of your choice. + * This call must be made before starting the provisioning. + */ + wifi_prov_mgr_endpoint_create("custom-data"); + /* Start provisioning service */ + ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning(security, pop, service_name, service_key)); + + /* The handler for the optional endpoint created above. + * This call must be made after starting the provisioning, and only if the endpoint + * has already been created above. + */ + wifi_prov_mgr_endpoint_register("custom-data", custom_prov_data_handler, NULL); + + /* Uncomment the following to wait for the provisioning to finish and then release + * the resources of the manager. Since in this case de-initialization is triggered + * by the default event loop handler, we don't need to call the following */ + // wifi_prov_mgr_wait(); + // wifi_prov_mgr_deinit(); + } else { + ESP_LOGI(TAG, "Already provisioned, starting Wi-Fi STA"); + + /* We don't need the manager as device is already provisioned, + * so let's release it's resources */ + wifi_prov_mgr_deinit(); + + /* Start Wi-Fi station */ + wifi_init_sta(); + } + + /* Wait for Wi-Fi connection */ + xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_EVENT, false, true, portMAX_DELAY); +} diff --git a/src/main/network_mngr.h b/src/main/network_mngr.h new file mode 100644 index 0000000..8b7ccf4 --- /dev/null +++ b/src/main/network_mngr.h @@ -0,0 +1,10 @@ +#ifndef _NETWORK_MNGR_H_ +#define _NETWORK_MNGR_H_ + +#include + +void networkInit(bool forceProv); + + + +#endif // _NETWORK_MNGR_H_ \ No newline at end of file diff --git a/tools/startBuildEnv.sh b/tools/startBuildEnv.sh old mode 100644 new mode 100755