wifi_cmd.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  2. * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "esp_log.h"
  9. #include "esp_wifi.h"
  10. #include "esp_console.h"
  11. #include "linenoise/linenoise.h"
  12. #include "argtable3/argtable3.h"
  13. #include "esp_pm.h"
  14. #include "esp_private/esp_clk.h"
  15. #define MAX_RECONNECT_TIMES (5)
  16. const static char *TAG = "WIFI";
  17. static int s_reconnect_times = 0;
  18. static void wifi_event_any_handler(void* arg, esp_event_base_t event_base,
  19. int32_t event_id, void* event_data)
  20. {
  21. ESP_LOGI(TAG, "WiFi event: 0x%"PRIx32, event_id);
  22. }
  23. static void wifi_event_disconnected_handler(void* arg, esp_event_base_t event_base,
  24. int32_t event_id, void* event_data)
  25. {
  26. ESP_LOGI(TAG, "WIFI_EVENT_STA_DISCONNECTED");
  27. if (s_reconnect_times++ < MAX_RECONNECT_TIMES) {
  28. esp_wifi_connect();
  29. } else {
  30. ESP_LOGE(TAG, "MAX RECONNECT TIME, STOP!");
  31. }
  32. }
  33. static void wifi_event_connected_handler(void* arg, esp_event_base_t event_base,
  34. int32_t event_id, void* event_data)
  35. {
  36. ESP_LOGI(TAG, "WIFI_EVENT_STA_CONNECTED");
  37. s_reconnect_times = 0;
  38. }
  39. static void ip_event_got_ip_handler(void* arg, esp_event_base_t event_base,
  40. int32_t event_id, void* event_data)
  41. {
  42. ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
  43. ESP_LOGI(TAG, "STA_GOT_IP:" IPSTR, IP2STR(&event->ip_info.ip));
  44. }
  45. static int initialize_wifi(int argc, char **argv)
  46. {
  47. wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  48. ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  49. esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_any_handler, NULL);
  50. esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, wifi_event_disconnected_handler, NULL);
  51. esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, wifi_event_connected_handler, NULL);
  52. esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, ip_event_got_ip_handler, NULL);
  53. ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
  54. ESP_ERROR_CHECK(esp_wifi_start() );
  55. /* always enable wifi sleep */
  56. ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_MIN_MODEM));
  57. ESP_LOGI(TAG, "initialize_wifi DONE.");
  58. return 0;
  59. }
  60. static void register_wifi_init(void)
  61. {
  62. const esp_console_cmd_t cmd = {
  63. .command = "wifi_init",
  64. .help = "Initialize WiFi",
  65. .hint = NULL,
  66. .func = &initialize_wifi,
  67. .argtable = NULL
  68. };
  69. ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
  70. }
  71. typedef struct {
  72. struct arg_str *ssid;
  73. struct arg_str *password;
  74. struct arg_int *authmode;
  75. struct arg_int *channel;
  76. struct arg_int *max_conn;
  77. struct arg_end *end;
  78. } ap_set_args_t;
  79. static ap_set_args_t ap_set_args;
  80. static int cmd_do_ap_set(int argc, char **argv)
  81. {
  82. int nerrors = arg_parse(argc, argv, (void **) &ap_set_args);
  83. if (nerrors != 0) {
  84. arg_print_errors(stderr, ap_set_args.end, argv[0]);
  85. return 1;
  86. }
  87. wifi_config_t wifi_config = {};
  88. const char *ssid = ap_set_args.ssid->sval[0];
  89. strncpy((char *) wifi_config.ap.ssid, ssid, sizeof(wifi_config.ap.ssid));
  90. const char *pass = ap_set_args.password->sval[0];
  91. if (ap_set_args.password->count > 0) {
  92. strncpy((char *) wifi_config.ap.password, pass, sizeof(wifi_config.ap.password));
  93. wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK; // set default auth mode
  94. }
  95. if (ap_set_args.channel->count > 0) {
  96. wifi_config.sta.channel = (uint8_t)(ap_set_args.channel->ival[0]);
  97. }
  98. if (ap_set_args.authmode->count > 0) {
  99. wifi_config.ap.authmode = ap_set_args.authmode->ival[0];
  100. }
  101. if (ap_set_args.max_conn->count > 0) {
  102. wifi_config.ap.max_connection = ap_set_args.max_conn->ival[0];
  103. } else {
  104. wifi_config.ap.max_connection = 2;
  105. }
  106. ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP) );
  107. esp_err_t err = esp_wifi_set_config(WIFI_IF_AP, &wifi_config);
  108. if (err == ESP_OK) {
  109. ESP_LOGI(TAG, "set ap config OK.");
  110. } else {
  111. ESP_LOGE(TAG, "set ap config Failed! (%s)", esp_err_to_name(err));
  112. }
  113. return 0;
  114. }
  115. static void register_ap_set(void)
  116. {
  117. ap_set_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
  118. ap_set_args.password = arg_str0(NULL, NULL, "<pass>", "password of AP");
  119. ap_set_args.authmode = arg_int0("a", "authmode", "<authmode>", "wifi auth type (ie. open | wep| wpa2 | wpa2_enterprise)");
  120. ap_set_args.channel = arg_int0("n", "channel", "<channel>", "channel of AP");
  121. ap_set_args.max_conn = arg_int0("m", "max_conn", "<max_conn>", "Max station number, default: 2");
  122. ap_set_args.end = arg_end(2);
  123. const esp_console_cmd_t cmd = {
  124. .command = "ap_set",
  125. .help = "WiFi is ap mode, set ap config.",
  126. .hint = NULL,
  127. .func = &cmd_do_ap_set,
  128. .argtable = &ap_set_args
  129. };
  130. ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
  131. }
  132. typedef struct {
  133. struct arg_str *ssid;
  134. struct arg_str *password;
  135. struct arg_int *channel;
  136. struct arg_end *end;
  137. } sta_connect_args_t;
  138. static sta_connect_args_t connect_args;
  139. static int cmd_do_sta_connect(int argc, char **argv)
  140. {
  141. int nerrors = arg_parse(argc, argv, (void **) &connect_args);
  142. if (nerrors != 0) {
  143. arg_print_errors(stderr, connect_args.end, argv[0]);
  144. return 1;
  145. }
  146. wifi_config_t wifi_config = {
  147. .sta = {
  148. .scan_method = WIFI_ALL_CHANNEL_SCAN,
  149. .sort_method = WIFI_CONNECT_AP_BY_SIGNAL,
  150. },
  151. };
  152. const char *ssid = connect_args.ssid->sval[0];
  153. memcpy((char *) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
  154. const char *pass = connect_args.password->sval[0];
  155. if (connect_args.password->count > 0) {
  156. memcpy((char *) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password));
  157. wifi_config.sta.threshold.authmode = WIFI_AUTH_WEP;
  158. }
  159. if (connect_args.channel->count > 0) {
  160. wifi_config.sta.channel = (uint8_t)(connect_args.channel->ival[0]);
  161. }
  162. ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
  163. ESP_LOGI(TAG, "Connecting to %s...", ssid);
  164. ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
  165. s_reconnect_times = 0;
  166. esp_err_t err = esp_wifi_connect();
  167. ESP_LOGI(TAG, "WIFI_CONNECT_START, ret: 0x%x", err);
  168. return 0;
  169. }
  170. static void register_sta_connect(void)
  171. {
  172. connect_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
  173. connect_args.password = arg_str0(NULL, NULL, "<pass>", "password of AP");
  174. connect_args.channel = arg_int0("n", "channel", "<channel>", "channel of AP");
  175. connect_args.end = arg_end(2);
  176. const esp_console_cmd_t cmd = {
  177. .command = "sta_connect",
  178. .help = "WiFi is station mode, join specified soft-AP",
  179. .hint = NULL,
  180. .func = &cmd_do_sta_connect,
  181. .argtable = &connect_args
  182. };
  183. ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
  184. }
  185. typedef struct {
  186. struct arg_str *type;
  187. struct arg_end *end;
  188. } light_sleep_args_t;
  189. static light_sleep_args_t sleep_args;
  190. static int cmd_do_light_sleep(int argc, char **argv)
  191. {
  192. int nerrors = arg_parse(argc, argv, (void **) &sleep_args);
  193. if (nerrors != 0) {
  194. arg_print_errors(stderr, sleep_args.end, argv[0]);
  195. return 1;
  196. }
  197. const char *sleep_type = sleep_args.type->sval[0];
  198. if (!strcmp(sleep_type, "enable")) {
  199. esp_pm_config_t pm_config = {
  200. .max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ,
  201. .min_freq_mhz = esp_clk_xtal_freq() / 1000000,
  202. .light_sleep_enable = true,
  203. };
  204. ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
  205. ESP_LOGI(TAG, "LIGHT_SLEEP_ENABLED,OK");
  206. } else {
  207. ESP_LOGE(TAG, "invaild arg!");
  208. return 1;
  209. }
  210. return 0;
  211. }
  212. static void register_light_sleep(void)
  213. {
  214. sleep_args.type = arg_str1(NULL, NULL, "<type>", "light sleep mode: enable");
  215. sleep_args.end = arg_end(2);
  216. const esp_console_cmd_t cmd = {
  217. .command = "light_sleep",
  218. .help = "Config light sleep mode",
  219. .hint = NULL,
  220. .func = &cmd_do_light_sleep,
  221. .argtable = &sleep_args,
  222. };
  223. ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
  224. }
  225. extern void register_wifi_cmd(void)
  226. {
  227. register_wifi_init();
  228. register_ap_set();
  229. register_sta_connect();
  230. register_light_sleep();
  231. }