1 /*
2  * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: CC0-1.0
5  */
6 
7 #include <string.h>
8 #include <stdlib.h>
9 #include "freertos/FreeRTOS.h"
10 #include "freertos/task.h"
11 #include "freertos/event_groups.h"
12 #include "esp_wifi.h"
13 #include "esp_wpa2.h"
14 #include "esp_event.h"
15 #include "esp_log.h"
16 #include "esp_system.h"
17 #include "nvs_flash.h"
18 #include "esp_netif.h"
19 
20 /* The examples use simple WiFi configuration that you can set via
21    project configuration menu.
22 
23    If you'd rather not, just change the below entries to strings with
24    the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
25 
26 */
27 #define EXAMPLE_WIFI_SSID CONFIG_EXAMPLE_WIFI_SSID
28 
29 #define EXAMPLE_EAP_ID CONFIG_EXAMPLE_EAP_ID
30 #define EXAMPLE_EAP_USERNAME CONFIG_EXAMPLE_EAP_USERNAME
31 #define EXAMPLE_EAP_PASSWORD CONFIG_EXAMPLE_EAP_PASSWORD
32 
33 /* FreeRTOS event group to signal when we are connected & ready to make a request */
34 static EventGroupHandle_t wifi_event_group;
35 
36 /* esp netif object representing the WIFI station */
37 static esp_netif_t *sta_netif = NULL;
38 
39 /* The event group allows multiple bits for each event,
40    but we only care about one event - are we connected
41    to the AP with an IP? */
42 const int CONNECTED_BIT = BIT0;
43 
44 static const char *TAG = "example";
45 
46 /* CA cert, taken from ca.pem
47 
48    To embed it in the app binary, the PEM, CRT and KEY file is named
49    in the component.mk COMPONENT_EMBED_TXTFILES variable.
50 */
51 #if defined(CONFIG_EXAMPLE_VALIDATE_SERVER_CERT)
52 extern uint8_t ca_pem_start[] asm("_binary_ca_pem_start");
53 extern uint8_t ca_pem_end[]   asm("_binary_ca_pem_end");
54 #endif
55 extern uint8_t pac_file_pac_start[] asm("_binary_pac_file_pac_start");
56 extern uint8_t pac_file_pac_end[] asm("_binary_pac_file_pac_end");
57 
event_handler(void * arg,esp_event_base_t event_base,int32_t event_id,void * event_data)58 static void event_handler(void* arg, esp_event_base_t event_base,
59                                 int32_t event_id, void* event_data)
60 {
61     if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
62         esp_wifi_connect();
63     } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
64         esp_wifi_connect();
65         xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
66     } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
67         xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
68     }
69 }
70 
initialise_wifi(void)71 static void initialise_wifi(void)
72 {
73 #if defined(CONFIG_EXAMPLE_VALIDATE_SERVER_CERT)
74     unsigned int ca_pem_bytes = ca_pem_end - ca_pem_start;
75 #endif
76     unsigned int pac_file_bytes = pac_file_pac_end - pac_file_pac_start;
77 
78     ESP_ERROR_CHECK(esp_netif_init());
79     wifi_event_group = xEventGroupCreate();
80     ESP_ERROR_CHECK(esp_event_loop_create_default());
81     sta_netif = esp_netif_create_default_wifi_sta();
82     assert(sta_netif);
83 
84     wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
85     ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
86     ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) );
87     ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );
88     ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
89     wifi_config_t wifi_config = {
90         .sta = {
91             .ssid = EXAMPLE_WIFI_SSID,
92 #if defined(CONFIG_EXAMPLE_WPA3_ENTERPRISE)
93             .pmf_cfg = {
94                 .capable = true,
95                 .required = false
96             },
97 #endif
98         },
99     };
100     ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
101     ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
102     ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
103     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)EXAMPLE_EAP_ID, strlen(EXAMPLE_EAP_ID)) );
104 
105 #if defined(CONFIG_EXAMPLE_VALIDATE_SERVER_CERT) || \
106     defined(CONFIG_EXAMPLE_WPA3_ENTERPRISE)
107     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_ca_cert(ca_pem_start, ca_pem_bytes) );
108 #endif /* CONFIG_EXAMPLE_VALIDATE_SERVER_CERT */ /* EXAMPLE_WPA3_ENTERPRISE */
109 
110     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_username((uint8_t *)EXAMPLE_EAP_USERNAME, strlen(EXAMPLE_EAP_USERNAME)) );
111     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_password((uint8_t *)EXAMPLE_EAP_PASSWORD, strlen(EXAMPLE_EAP_PASSWORD)) );
112     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_pac_file(pac_file_pac_start, pac_file_bytes - 1) );
113     esp_eap_fast_config eap_fast_config = {
114         .fast_provisioning = 2,
115         .fast_max_pac_list_len = 0,
116         .fast_pac_format_binary = false
117     };
118     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_fast_phase1_params(eap_fast_config) );
119 
120     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_enable() );
121     ESP_ERROR_CHECK( esp_wifi_start() );
122 }
123 
wpa2_enterprise_example_task(void * pvParameters)124 static void wpa2_enterprise_example_task(void *pvParameters)
125 {
126     esp_netif_ip_info_t ip;
127     memset(&ip, 0, sizeof(esp_netif_ip_info_t));
128     vTaskDelay(2000 / portTICK_PERIOD_MS);
129 
130     while (1) {
131         vTaskDelay(5000 / portTICK_PERIOD_MS);
132 
133         if (esp_netif_get_ip_info(sta_netif, &ip) == 0) {
134             ESP_LOGI(TAG, "~~~~~~~~~~~");
135             ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip.ip));
136             ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip.netmask));
137             ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip.gw));
138             ESP_LOGI(TAG, "~~~~~~~~~~~");
139         }
140     }
141 }
142 
app_main(void)143 void app_main(void)
144 {
145     ESP_ERROR_CHECK( nvs_flash_init() );
146     initialise_wifi();
147     xTaskCreate(&wpa2_enterprise_example_task, "wpa2_enterprise_example_task", 4096, NULL, 5, NULL);
148 }
149