forked from espressif/esp-protocols
		
	
		
			
				
	
	
		
			285 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
 | |
|  *
 | |
|  * SPDX-License-Identifier: Apache-2.0
 | |
|  */
 | |
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #include "sdkconfig.h"
 | |
| #include "freertos/FreeRTOS.h"
 | |
| #include "freertos/event_groups.h"
 | |
| #include "esp_netif.h"
 | |
| #include "esp_console.h"
 | |
| #include "esp_event.h"
 | |
| #include "esp_log.h"
 | |
| #include "esp_netif_net_stack.h"
 | |
| #include "lwip/ip6.h"
 | |
| #include "lwip/opt.h"
 | |
| #include "esp_wifi.h"
 | |
| #include "console_wifi.h"
 | |
| 
 | |
| 
 | |
| #define DEFAULT_SCAN_LIST_SIZE 10
 | |
| 
 | |
| #if CONFIG_WIFI_CMD_AUTO_REGISTRATION
 | |
| /**
 | |
|  * Static registration of this plugin is achieved by defining the plugin description
 | |
|  * structure and placing it into .console_cmd_desc section.
 | |
|  * The name of the section and its placement is determined by linker.lf file in 'plugins' component.
 | |
|  */
 | |
| static const console_cmd_plugin_desc_t __attribute__((section(".console_cmd_desc"), used)) PLUGIN = {
 | |
|     .name = "console_cmd_wifi",
 | |
|     .plugin_regd_fn = &console_cmd_wifi_register
 | |
| };
 | |
| #endif
 | |
| 
 | |
| typedef struct wifi_op_t {
 | |
|     char *name;
 | |
|     esp_err_t (*operation)(struct wifi_op_t *self, int argc, char *argv[]);
 | |
|     int arg_cnt;
 | |
|     int start_index;
 | |
|     char *help;
 | |
| } wifi_op_t;
 | |
| 
 | |
| static esp_err_t wifi_help_op(wifi_op_t *self, int argc, char *argv[]);
 | |
| static esp_err_t wifi_show_op(wifi_op_t *self, int argc, char *argv[]);
 | |
| static esp_err_t wifi_sta_join_op(wifi_op_t *self, int argc, char *argv[]);
 | |
| static esp_err_t wifi_sta_leave_op(wifi_op_t *self, int argc, char *argv[]);
 | |
| 
 | |
| static const char *TAG = "console_wifi";
 | |
| 
 | |
| #define JOIN_TIMEOUT_MS (10000)
 | |
| 
 | |
| static EventGroupHandle_t wifi_event_group;
 | |
| static const int STA_STARTED_BIT = BIT0;
 | |
| static const int CONNECTED_BIT = BIT1;
 | |
| 
 | |
| static wifi_op_t cmd_list[] = {
 | |
|     {.name = "help", .operation = wifi_help_op, .arg_cnt = 2, .start_index = 1, .help = "wifi help: Prints the help text for all wifi commands"},
 | |
|     {.name = "show", .operation = wifi_show_op, .arg_cnt = 3, .start_index = 1, .help = "wifi show network/sta: Scans and displays all available wifi APs./ Shows the details of wifi station."},
 | |
|     {.name = "join",  .operation = wifi_sta_join_op,  .arg_cnt = 5, .start_index = 2, .help = "wifi sta join <network ssid> <password>: Station joins the given wifi network."},
 | |
|     {.name = "join",  .operation = wifi_sta_join_op,  .arg_cnt = 4, .start_index = 2, .help = "wifi sta join <network ssid>: Station joins the given unsecured wifi network."},
 | |
|     {.name = "join",  .operation = wifi_sta_join_op,  .arg_cnt = 3, .start_index = 2, .help = "wifi sta join: Station joins the pre-configured wifi network."},
 | |
|     {.name = "leave", .operation = wifi_sta_leave_op,  .arg_cnt = 3, .start_index = 2, .help = "wifi sta leave: Station leaves the wifi network."},
 | |
| };
 | |
| 
 | |
| static void event_handler(void *arg, esp_event_base_t event_base,
 | |
|                           int32_t event_id, void *event_data)
 | |
| {
 | |
|     if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
 | |
|         xEventGroupSetBits(wifi_event_group, STA_STARTED_BIT);
 | |
|     } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
 | |
|         esp_wifi_connect();
 | |
|         xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
 | |
|     } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
 | |
|         xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static esp_err_t wifi_help_op(wifi_op_t *self, int argc, char *argv[])
 | |
| {
 | |
|     int cmd_count = sizeof(cmd_list) / sizeof(cmd_list[0]);
 | |
| 
 | |
|     for (int i = 0; i < cmd_count; i++) {
 | |
|         if ((cmd_list[i].help != NULL) && (strlen(cmd_list[i].help) != 0)) {
 | |
|             printf(" %s\n", cmd_list[i].help);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return ESP_OK;
 | |
| }
 | |
| 
 | |
| uint8_t wifi_connection_status = 0;
 | |
| 
 | |
| void wifi_init(void)
 | |
| {
 | |
|     static bool init_flag = false;
 | |
|     if (init_flag) {
 | |
|         return;
 | |
|     }
 | |
|     wifi_event_group = xEventGroupCreate();
 | |
| 
 | |
|     esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
 | |
|     assert(sta_netif);
 | |
| 
 | |
|     wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
 | |
|     ESP_ERROR_CHECK(esp_wifi_init(&cfg));
 | |
| 
 | |
|     ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_START, &event_handler, NULL));
 | |
|     ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &event_handler, NULL));
 | |
|     ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
 | |
| 
 | |
|     ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
 | |
|     ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
 | |
| 
 | |
|     ESP_ERROR_CHECK(esp_wifi_start());
 | |
| 
 | |
|     int bits = xEventGroupWaitBits(wifi_event_group, STA_STARTED_BIT,
 | |
|                                    pdFALSE, pdTRUE, JOIN_TIMEOUT_MS / portTICK_PERIOD_MS);
 | |
| 
 | |
|     if ((bits & STA_STARTED_BIT) == 0) {
 | |
|         ESP_LOGE(TAG, "Error: Wifi Connection timed out");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     init_flag = true;
 | |
| }
 | |
| 
 | |
| /* Initialize Wi-Fi as sta and set scan method */
 | |
| static void wifi_scan(void)
 | |
| {
 | |
|     uint16_t number = DEFAULT_SCAN_LIST_SIZE;
 | |
|     wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];
 | |
|     uint16_t ap_count = 0;
 | |
| 
 | |
|     memset(ap_info, 0, sizeof(ap_info));
 | |
| 
 | |
|     wifi_init();
 | |
| 
 | |
|     esp_wifi_scan_start(NULL, true);
 | |
|     ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));
 | |
|     ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));
 | |
| 
 | |
|     ESP_LOGI(TAG, "Showing Wifi networks");
 | |
|     ESP_LOGI(TAG, "*********************");
 | |
|     for (int i = 0; i < number; i++) {
 | |
|         ESP_LOGI(TAG, "RSSI: %d\tChannel: %d\tSSID: %s", ap_info[i].rssi, ap_info[i].primary, ap_info[i].ssid);
 | |
|     }
 | |
|     ESP_LOGI(TAG, "Total APs scanned = %u, actual AP number ap_info holds = %u", ap_count, number);
 | |
| }
 | |
| 
 | |
| static esp_err_t wifi_show_op(wifi_op_t *self, int argc, char *argv[])
 | |
| {
 | |
|     if (!strcmp("network", argv[self->start_index + 1])) {
 | |
|         wifi_scan();
 | |
|         return ESP_OK;
 | |
|     }
 | |
| 
 | |
|     if (!strcmp("sta", argv[self->start_index + 1])) {
 | |
|         {
 | |
|             wifi_config_t wifi_config = { 0 };
 | |
| 
 | |
|             wifi_init();
 | |
|             ESP_ERROR_CHECK(esp_wifi_get_config(WIFI_IF_STA, &wifi_config));
 | |
| 
 | |
|             ESP_LOGI(TAG, "Showing Joind AP details:");
 | |
|             ESP_LOGI(TAG, "*************************");
 | |
|             ESP_LOGI(TAG, "SSID: %s", wifi_config.sta.ssid);
 | |
|             ESP_LOGI(TAG, "Channel: %d", wifi_config.sta.channel);
 | |
|             ESP_LOGI(TAG, "bssid: %02x:%02x:%02x:%02x:%02x:%02x", wifi_config.sta.bssid[0],
 | |
|                      wifi_config.sta.bssid[1], wifi_config.sta.bssid[2], wifi_config.sta.bssid[3],
 | |
|                      wifi_config.sta.bssid[4], wifi_config.sta.bssid[5]);
 | |
|         }
 | |
|         return ESP_OK;
 | |
|     }
 | |
| 
 | |
|     return ESP_OK;
 | |
| }
 | |
| 
 | |
| static esp_err_t wifi_sta_join_op(wifi_op_t *self, int argc, char *argv[])
 | |
| {
 | |
|     wifi_config_t wifi_config = { 0 };
 | |
| 
 | |
|     if (strcmp("sta", argv[self->start_index - 1])) {
 | |
|         ESP_LOGE(TAG, "Error: Invalid command\n");
 | |
|         ESP_LOGE(TAG, "%s\n", self->help);
 | |
|         return ESP_FAIL;
 | |
|     }
 | |
| 
 | |
|     if (self->arg_cnt == 3) {
 | |
|         strlcpy((char *) wifi_config.sta.ssid, CONFIG_WIFI_CMD_NETWORK_SSID, sizeof(wifi_config.sta.ssid));
 | |
|         strlcpy((char *) wifi_config.sta.password, CONFIG_WIFI_CMD_NETWORK_PASSWORD, sizeof(wifi_config.sta.password));
 | |
|     } else {
 | |
|         strlcpy((char *) wifi_config.sta.ssid, argv[self->start_index + 1], sizeof(wifi_config.sta.ssid));
 | |
|     }
 | |
| 
 | |
|     if (self->arg_cnt == 5) {
 | |
|         strlcpy((char *) wifi_config.sta.password, argv[self->start_index + 2], sizeof(wifi_config.sta.password));
 | |
|     }
 | |
| 
 | |
|     wifi_init();
 | |
|     ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
 | |
|     esp_wifi_connect();
 | |
| 
 | |
|     int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
 | |
|                                    pdFALSE, pdTRUE, JOIN_TIMEOUT_MS / portTICK_PERIOD_MS);
 | |
| 
 | |
|     if ((bits & CONNECTED_BIT) == 0) {
 | |
|         ESP_LOGE(TAG, "Error: Wifi Connection timed out");
 | |
|         return ESP_OK;
 | |
|     }
 | |
| 
 | |
|     return ESP_OK;
 | |
| }
 | |
| 
 | |
| static esp_err_t wifi_sta_leave_op(wifi_op_t *self, int argc, char *argv[])
 | |
| {
 | |
|     wifi_config_t wifi_config = { 0 };
 | |
| 
 | |
|     if (strcmp("sta", argv[self->start_index - 1])) {
 | |
|         ESP_LOGE(TAG, "Error: Invalid command\n");
 | |
|         ESP_LOGE(TAG, "%s\n", self->help);
 | |
|         return ESP_FAIL;
 | |
|     }
 | |
| 
 | |
|     esp_wifi_disconnect();
 | |
|     ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
 | |
| 
 | |
|     return ESP_OK;
 | |
| }
 | |
| 
 | |
| /* handle 'wifi' command */
 | |
| static esp_err_t do_cmd_wifi(int argc, char **argv)
 | |
| {
 | |
|     int cmd_count = sizeof(cmd_list) / sizeof(cmd_list[0]);
 | |
|     wifi_op_t cmd;
 | |
| 
 | |
|     for (int i = 0; i < cmd_count; i++) {
 | |
|         cmd = cmd_list[i];
 | |
| 
 | |
|         if (argc < cmd.start_index + 1) {
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (!strcmp(cmd.name, argv[cmd.start_index])) {
 | |
|             /* Get interface for eligible commands */
 | |
|             if (cmd.arg_cnt == argc) {
 | |
|                 if (cmd.operation != NULL) {
 | |
|                     if (cmd.operation(&cmd, argc, argv) != ESP_OK) {
 | |
|                         ESP_LOGE(TAG, "Usage:\n%s", cmd.help);
 | |
|                         return 0;
 | |
|                     }
 | |
|                 }
 | |
|                 return ESP_OK;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     ESP_LOGE(TAG, "Command not available");
 | |
| 
 | |
|     return ESP_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief Registers the wifi command.
 | |
|  *
 | |
|  * @return
 | |
|  *          - esp_err_t
 | |
|  */
 | |
| esp_err_t console_cmd_wifi_register(void)
 | |
| {
 | |
|     esp_err_t ret = ESP_OK;
 | |
|     esp_console_cmd_t command = {
 | |
|         .command = "wifi",
 | |
|         .help = "Command for wifi configuration and monitoring\n For more info run 'wifi help'",
 | |
|         .func = &do_cmd_wifi
 | |
|     };
 | |
| 
 | |
|     ret = esp_console_cmd_register(&command);
 | |
|     if (ret) {
 | |
|         ESP_LOGE(TAG, "Unable to register wifi");
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 |