network_manager_handlers.c 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155
  1. #ifdef NETWORK_HANDLERS_LOG_LEVEL
  2. #define LOG_LOCAL_LEVEL NETWORK_HANDLERS_LOG_LEVEL
  3. #endif
  4. #include "network_manager.h"
  5. #include <stdbool.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "network_ethernet.h"
  10. #include "network_status.h"
  11. #include "network_wifi.h"
  12. #include "dns_server.h"
  13. #include "esp_log.h"
  14. #include "esp_system.h"
  15. #include "freertos/FreeRTOS.h"
  16. #include "platform_esp32.h"
  17. #include "esp_netif.h"
  18. #include "freertos/task.h"
  19. #include "cJSON.h"
  20. #include "cmd_system.h"
  21. #include "esp_app_format.h"
  22. #include "esp_event.h"
  23. #include "esp_ota_ops.h"
  24. #include "esp_wifi.h"
  25. #include "esp_wifi_types.h"
  26. #include "lwip/api.h"
  27. #include "lwip/err.h"
  28. #include "lwip/ip4_addr.h"
  29. #include "lwip/netdb.h"
  30. #include "mdns.h"
  31. #include "messaging.h"
  32. #include "platform_config.h"
  33. #include "trace.h"
  34. #include "accessors.h"
  35. #include "esp_err.h"
  36. #include "globdefs.h"
  37. #include "http_server_handlers.h"
  38. #include "network_manager.h"
  39. static const char TAG[]="network_handlers";
  40. EXT_RAM_ATTR static state_t network_states[TOTAL_NM_STATE];
  41. EXT_RAM_ATTR static state_t Wifi_Active_State[TOTAL_WIFI_ACTIVE_STATE];
  42. EXT_RAM_ATTR static state_t Eth_Active_State[TOTAL_ETH_ACTIVE_STATE];
  43. EXT_RAM_ATTR static state_t Wifi_Configuring_State[TOTAL_WIFI_CONFIGURING_STATE];
  44. static void network_interface_coexistence(state_machine_t* state_machine);
  45. static state_machine_result_t local_traverse_state(state_machine_t* const state_machine,
  46. const state_t* const target_state, const char * caller) ;
  47. static state_machine_result_t local_switch_state(state_machine_t* state_machine,
  48. const state_t* const target_state, const char * caller);
  49. void network_execute_cb(state_machine_t* const state_machine, const char * caller);
  50. int get_root_id(const state_t * state);
  51. const state_t* get_root( const state_t* const state);
  52. #define ADD_ROOT(name,...) ADD_ROOT_FORWARD_DECLARATION(name,...)
  53. #define ADD_ROOT_LEAF(name,...) ADD_ROOT_LEAF_FORWARD_DECLARATION(name,...)
  54. #define ADD_LEAF(name,...) ADD_LEAF_FORWARD_DECLARATION(name,...)
  55. ALL_NM_STATE
  56. ALL_ETH_STATE(, )
  57. ALL_WIFI_STATE(, )
  58. ALL_WIFI_CONFIGURING_STATE(, )
  59. #undef ADD_ROOT
  60. #undef ADD_ROOT_LEAF
  61. #undef ADD_LEAF
  62. /*
  63. * --------------------- Global variables ---------------------
  64. */
  65. #define ADD_ROOT(NAME, CHILD) ADD_ROOT_(NAME, CHILD)
  66. #define ADD_LEAF(NAME, PARENT, LEVEL) ADD_LEAF_(NAME, PARENT, LEVEL)
  67. #define ADD_ROOT_LEAF(NAME) ADD_ROOT_LEAF_(NAME)
  68. #define ADD_ROOT_(NAME, CHILD) \
  69. [NAME] = { \
  70. .Handler = NAME##_handler, \
  71. .Entry = NAME##_entry_handler, \
  72. .Exit = NAME##_exit_handler, \
  73. .Level = 0, \
  74. .Parent = NULL, \
  75. .Id = NAME, \
  76. .Node = CHILD, \
  77. },
  78. #define ADD_ROOT_LEAF_(NAME) \
  79. [NAME] = { \
  80. .Handler = NAME##_handler, \
  81. .Entry = NAME##_entry_handler, \
  82. .Exit = NAME##_exit_handler, \
  83. .Id = NAME, \
  84. .Parent = NULL, \
  85. },
  86. #define ADD_LEAF_(NAME, PARENT, LEVEL) \
  87. [NAME] = { \
  88. .Handler = NAME##_handler, \
  89. .Entry = NAME##_entry_handler, \
  90. .Exit = NAME##_exit_handler, \
  91. .Id = NAME, \
  92. .Level = LEVEL, \
  93. .Parent = PARENT, \
  94. },
  95. static void network_initialize_state_machine_globals(){
  96. static state_t loc_network_states[] =
  97. {
  98. ALL_NM_STATE};
  99. static state_t loc_Wifi_Active_State[] = {
  100. ALL_WIFI_STATE(&network_states[NETWORK_WIFI_ACTIVE_STATE], 1)
  101. };
  102. static state_t loc_Eth_Active_State[]={
  103. ALL_ETH_STATE(&network_states[NETWORK_ETH_ACTIVE_STATE], 1)
  104. };
  105. static state_t loc_Wifi_Configuring_State[]={
  106. ALL_WIFI_CONFIGURING_STATE(&network_states[NETWORK_WIFI_CONFIGURING_ACTIVE_STATE], 1)
  107. };
  108. memcpy(&network_states,&loc_network_states,sizeof(network_states));
  109. memcpy(&Eth_Active_State,&loc_Eth_Active_State,sizeof(Eth_Active_State));
  110. memcpy(&Wifi_Active_State,&loc_Wifi_Active_State,sizeof(Wifi_Active_State));
  111. memcpy(&Wifi_Configuring_State,&loc_Wifi_Configuring_State,sizeof(Wifi_Configuring_State));
  112. }
  113. #undef ADD_ROOT
  114. #undef ADD_ROOT_LEAF
  115. #undef ADD_LEAF
  116. #define HANDLE_GLOBAL_EVENT(m) \
  117. if (handle_global_event(m) == EVENT_HANDLED) \
  118. return EVENT_HANDLED;
  119. static void network_connect_active_ssid(state_machine_t* const State_Machine) {
  120. network_t* const nm = (network_t*)State_Machine;
  121. if (network_wifi_connect_active_ssid() != ESP_OK) {
  122. ESP_LOGE(TAG, "Oups. Something went wrong!");
  123. nm->wifi_connected = false;
  124. ESP_LOGD(TAG, "Checking if ethernet interface is connected");
  125. if (network_is_interface_connected(nm->eth_netif)) {
  126. ESP_LOGD(TAG, "Ethernet connection is found. Try to fallback there");
  127. network_async(EN_ETHERNET_FALLBACK);
  128. } else {
  129. // returning to AP mode
  130. nm->STA_duration = STA_POLLING_MIN;
  131. ESP_LOGD(TAG, "No ethernet and no wifi configured. Go to configuration mode");
  132. network_async_configure();
  133. }
  134. }
  135. }
  136. void initialize_network_handlers(state_machine_t* state_machine){
  137. MEMTRACE_PRINT_DELTA();
  138. network_initialize_state_machine_globals();
  139. MEMTRACE_PRINT_DELTA();
  140. NETWORK_INSTANTIATED_STATE_handler(state_machine);
  141. MEMTRACE_PRINT_DELTA();
  142. }
  143. static state_machine_result_t handle_global_event(state_machine_t* state_machine) {
  144. network_t * net_sm= ((network_t *)state_machine);
  145. switch (net_sm->Machine.Event) {
  146. case EN_UPDATE_STATUS:
  147. // handle the event, but don't swicth
  148. network_status_update_basic_info();
  149. return EVENT_HANDLED;
  150. /* code */
  151. break;
  152. case EN_REBOOT:
  153. ESP_LOGD(TAG,"Called for reboot type %d",net_sm->event_parameters->rtype);
  154. switch (net_sm->event_parameters->rtype) {
  155. case OTA:
  156. ESP_LOGD(TAG, " Calling guided_restart_ota.");
  157. guided_restart_ota();
  158. break;
  159. case RECOVERY:
  160. ESP_LOGD(TAG, " Calling guided_factory.");
  161. guided_factory();
  162. break;
  163. case RESTART:
  164. ESP_LOGD(TAG, " Calling simple_restart.");
  165. simple_restart();
  166. break;
  167. default:
  168. break;
  169. }
  170. return EVENT_UN_HANDLED;
  171. break;
  172. case EN_REBOOT_URL:
  173. if (net_sm->event_parameters->strval) {
  174. start_ota(net_sm->event_parameters->strval, NULL, 0);
  175. FREE_AND_NULL(net_sm->event_parameters->strval);
  176. }
  177. return EVENT_UN_HANDLED;
  178. break;
  179. default:
  180. break;
  181. }
  182. return EVENT_UN_HANDLED;
  183. }
  184. /*********************************************************************************************
  185. * INSTANTIATED_STATE
  186. */
  187. static state_machine_result_t NETWORK_INSTANTIATED_STATE_entry_handler(state_machine_t* const State_Machine) {
  188. network_handler_entry_print(State_Machine,true);
  189. NETWORK_EXECUTE_CB(State_Machine);
  190. network_handler_entry_print(State_Machine,false);
  191. return EVENT_HANDLED;
  192. }
  193. static state_machine_result_t NETWORK_INSTANTIATED_STATE_handler(state_machine_t* const State_Machine) {
  194. network_handler_print(State_Machine,true);
  195. state_machine_result_t result = EVENT_UN_HANDLED;
  196. State_Machine->State = &network_states[NETWORK_INSTANTIATED_STATE];
  197. State_Machine->Event = EN_START;
  198. HANDLE_GLOBAL_EVENT(State_Machine);
  199. if (State_Machine->Event == EN_START) {
  200. result= local_traverse_state(State_Machine, &network_states[NETWORK_INITIALIZING_STATE],__FUNCTION__);
  201. }
  202. network_handler_print(State_Machine,false);
  203. return result;
  204. }
  205. static state_machine_result_t NETWORK_INSTANTIATED_STATE_exit_handler(state_machine_t* const State_Machine) {
  206. network_exit_handler_print(State_Machine,true);
  207. network_exit_handler_print(State_Machine,false);
  208. return EVENT_HANDLED;
  209. }
  210. /*********************************************************************************************
  211. * INITIALIZING_STATE
  212. */
  213. static state_machine_result_t NETWORK_INITIALIZING_STATE_entry_handler(state_machine_t* const State_Machine) {
  214. network_handler_entry_print(State_Machine,true);
  215. MEMTRACE_PRINT_DELTA_MESSAGE(" Initializing tcp_ip adapter");
  216. esp_netif_init();
  217. MEMTRACE_PRINT_DELTA_MESSAGE(" Creating the default event loop");
  218. ESP_ERROR_CHECK(esp_event_loop_create_default());
  219. MEMTRACE_PRINT_DELTA_MESSAGE("Initializing network status");
  220. init_network_status();
  221. MEMTRACE_PRINT_DELTA_MESSAGE("Loading wifi global configuration");
  222. network_wifi_global_init();
  223. MEMTRACE_PRINT_DELTA_MESSAGE(" Registering event handler");
  224. esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &network_ip_event_handler, NULL);
  225. MEMTRACE_PRINT_DELTA_MESSAGE(" Initializing network done. Starting http server");
  226. // send a message to start the connections
  227. http_server_start();
  228. MEMTRACE_PRINT_DELTA_MESSAGE("Executing Callback");
  229. NETWORK_EXECUTE_CB(State_Machine);
  230. network_handler_entry_print(State_Machine,false);
  231. return EVENT_HANDLED;
  232. }
  233. static state_machine_result_t NETWORK_INITIALIZING_STATE_handler(state_machine_t* const State_Machine) {
  234. network_handler_print(State_Machine,true);
  235. state_machine_result_t result = EVENT_UN_HANDLED;
  236. HANDLE_GLOBAL_EVENT(State_Machine);
  237. switch (State_Machine->Event) {
  238. case EN_START:
  239. if (network_is_wifi_prioritized()) {
  240. ESP_LOGI(TAG, "WiFi connection is prioritized. Starting WiFi");
  241. result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_INITIALIZING_STATE],__FUNCTION__);
  242. }
  243. else {
  244. result= local_traverse_state(State_Machine, &Eth_Active_State[ETH_STARTING_STATE],__FUNCTION__);
  245. }
  246. break;
  247. default:
  248. result= EVENT_UN_HANDLED;
  249. }
  250. network_handler_print(State_Machine,false);
  251. return result;
  252. }
  253. static state_machine_result_t NETWORK_INITIALIZING_STATE_exit_handler(state_machine_t* const State_Machine) {
  254. network_exit_handler_print(State_Machine,true);
  255. network_exit_handler_print(State_Machine,false);
  256. return EVENT_HANDLED;
  257. }
  258. /*********************************************************************************************
  259. * ETH_STARTING_STATE
  260. */
  261. static state_machine_result_t ETH_STARTING_STATE_entry_handler(state_machine_t* const State_Machine) {
  262. network_handler_entry_print(State_Machine,true);
  263. ESP_LOGD(TAG, "Looking for ethernet Interface");
  264. network_t* const nm = (network_t *)State_Machine;
  265. init_network_ethernet();
  266. if (!network_ethernet_enabled()) {
  267. network_async_fail();
  268. } else {
  269. nm->eth_netif = network_ethernet_get_interface();
  270. }
  271. NETWORK_EXECUTE_CB(State_Machine);
  272. network_handler_entry_print(State_Machine,false);
  273. return EVENT_HANDLED;
  274. }
  275. static state_machine_result_t ETH_STARTING_STATE_handler(state_machine_t* const State_Machine) {
  276. state_machine_result_t result = EVENT_HANDLED;
  277. network_handler_print(State_Machine,true);
  278. HANDLE_GLOBAL_EVENT(State_Machine);
  279. switch (State_Machine->Event) {
  280. case EN_FAIL:
  281. result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_INITIALIZING_STATE],__FUNCTION__);
  282. break;
  283. case EN_SUCCESS:
  284. result= local_traverse_state(State_Machine, &network_states[NETWORK_ETH_ACTIVE_STATE],__FUNCTION__);
  285. break;
  286. default:
  287. ESP_LOGE(TAG, "No handler");
  288. result= EVENT_UN_HANDLED;
  289. }
  290. network_handler_print(State_Machine,false);
  291. return result;
  292. }
  293. static state_machine_result_t ETH_STARTING_STATE_exit_handler(state_machine_t* const State_Machine) {
  294. network_exit_handler_print(State_Machine,true);
  295. network_exit_handler_print(State_Machine,false);
  296. return EVENT_HANDLED;
  297. }
  298. /*********************************************************************************************
  299. * NETWORK_ETH_ACTIVE_STATE
  300. */
  301. static state_machine_result_t NETWORK_ETH_ACTIVE_STATE_entry_handler(state_machine_t* const State_Machine) {
  302. network_handler_entry_print(State_Machine,true);
  303. network_set_timer(ETH_LINK_DOWN_REBOOT);
  304. NETWORK_EXECUTE_CB(State_Machine);
  305. network_handler_entry_print(State_Machine,false);
  306. return EVENT_HANDLED;
  307. }
  308. static state_machine_result_t NETWORK_ETH_ACTIVE_STATE_handler(state_machine_t* const State_Machine) {
  309. network_handler_print(State_Machine,true);
  310. state_machine_result_t result = EVENT_UN_HANDLED;
  311. switch (State_Machine->Event) {
  312. case EN_CONNECT_NEW:
  313. result= local_traverse_state(State_Machine, &Eth_Active_State[ETH_CONNECTING_NEW_STATE],__FUNCTION__);
  314. break;
  315. case EN_LINK_UP:
  316. result= local_traverse_state(State_Machine, &Eth_Active_State[ETH_ACTIVE_LINKUP_STATE],__FUNCTION__);
  317. break;
  318. case EN_LINK_DOWN:
  319. result= local_traverse_state(State_Machine, &Eth_Active_State[ETH_ACTIVE_LINKDOWN_STATE],__FUNCTION__);
  320. break;
  321. case EN_ETH_GOT_IP:
  322. result= local_traverse_state(State_Machine, &Eth_Active_State[ETH_ACTIVE_CONNECTED_STATE],__FUNCTION__);
  323. break;
  324. case EN_ETHERNET_FALLBACK:
  325. result= local_traverse_state(State_Machine, &Eth_Active_State[ETH_ACTIVE_CONNECTED_STATE],__FUNCTION__);
  326. break;
  327. case EN_TIMER:
  328. ESP_LOGW(TAG, "Ethernet link timeout. Rebooting to wifi");
  329. network_prioritize_wifi(true);
  330. simple_restart();
  331. //result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_INITIALIZING_STATE],__FUNCTION__);
  332. break;
  333. case EN_SCAN:
  334. ESP_LOGW(TAG,"Wifi scan cannot be executed in this state");
  335. network_wifi_built_known_ap_list();
  336. break;
  337. case EN_DELETE: {
  338. ESP_LOGD(TAG, "WiFi disconnected by user");
  339. network_wifi_clear_config();
  340. network_status_update_ip_info(UPDATE_USER_DISCONNECT);
  341. result= EVENT_HANDLED;
  342. } break;
  343. default:
  344. HANDLE_GLOBAL_EVENT(State_Machine);
  345. result=EVENT_UN_HANDLED;
  346. }
  347. network_handler_print(State_Machine,false);
  348. return result;
  349. }
  350. static state_machine_result_t NETWORK_ETH_ACTIVE_STATE_exit_handler(state_machine_t* const State_Machine) {
  351. network_exit_handler_print(State_Machine,true);
  352. network_set_timer(0);
  353. network_exit_handler_print(State_Machine,false);
  354. return EVENT_HANDLED;
  355. }
  356. /*********************************************************************************************
  357. * ETH_CONNECTING_NEW_STATE
  358. */
  359. static state_machine_result_t ETH_CONNECTING_NEW_STATE_entry_handler(state_machine_t* const State_Machine) {
  360. network_t* const nm = (network_t *)State_Machine;
  361. network_handler_entry_print(State_Machine,true);
  362. network_start_stop_dhcp(nm->wifi_netif, true);
  363. network_wifi_connect(nm->event_parameters->ssid,nm->event_parameters->password);
  364. FREE_AND_NULL(nm->event_parameters->ssid);
  365. FREE_AND_NULL(nm->event_parameters->password);
  366. NETWORK_EXECUTE_CB(State_Machine);
  367. network_handler_entry_print(State_Machine,false);
  368. return EVENT_HANDLED;
  369. }
  370. static state_machine_result_t ETH_CONNECTING_NEW_STATE_handler(state_machine_t* const State_Machine) {
  371. HANDLE_GLOBAL_EVENT(State_Machine);
  372. network_handler_print(State_Machine,true);
  373. state_machine_result_t result = EVENT_HANDLED;
  374. switch (State_Machine->Event) {
  375. case EN_GOT_IP:
  376. result= local_traverse_state(State_Machine, &network_states[WIFI_CONNECTED_STATE],__FUNCTION__);
  377. break;
  378. case EN_LOST_CONNECTION:
  379. network_status_update_ip_info(UPDATE_FAILED_ATTEMPT);
  380. messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Unable to connect to new WiFi access point.");
  381. // no existing configuration, or wifi wasn't the active connection when connection
  382. // attempt was made
  383. network_async(EN_ETHERNET_FALLBACK);
  384. result = EVENT_HANDLED;
  385. break;
  386. default:
  387. result= EVENT_UN_HANDLED;
  388. }
  389. network_handler_print(State_Machine,false);
  390. return result;
  391. }
  392. static state_machine_result_t ETH_CONNECTING_NEW_STATE_exit_handler(state_machine_t* const State_Machine) {
  393. network_exit_handler_print(State_Machine,true);
  394. network_set_timer(0);
  395. network_exit_handler_print(State_Machine,false);
  396. return EVENT_HANDLED;
  397. }
  398. /*********************************************************************************************
  399. * ETH_ACTIVE_LINKDOWN
  400. */
  401. static state_machine_result_t ETH_ACTIVE_LINKDOWN_STATE_entry_handler(state_machine_t* const State_Machine) {
  402. network_handler_entry_print(State_Machine,true);
  403. network_set_timer(ETH_LINK_DOWN_REBOOT);
  404. NETWORK_EXECUTE_CB(State_Machine);
  405. messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Ethernet link down.");
  406. network_handler_entry_print(State_Machine,false);
  407. return EVENT_HANDLED;
  408. }
  409. static state_machine_result_t ETH_ACTIVE_LINKDOWN_STATE_handler(state_machine_t* const State_Machine) {
  410. network_handler_print(State_Machine,true);
  411. HANDLE_GLOBAL_EVENT(State_Machine);
  412. network_handler_print(State_Machine,false);
  413. return EVENT_UN_HANDLED;
  414. }
  415. static state_machine_result_t ETH_ACTIVE_LINKDOWN_STATE_exit_handler(state_machine_t* const State_Machine) {
  416. network_exit_handler_print(State_Machine,true);
  417. network_set_timer(0);
  418. network_exit_handler_print(State_Machine,false);
  419. return EVENT_HANDLED;
  420. }
  421. /*********************************************************************************************
  422. * ETH_ACTIVE_LINKUP_STATE
  423. */
  424. static state_machine_result_t ETH_ACTIVE_LINKUP_STATE_entry_handler(state_machine_t* const State_Machine) {
  425. network_handler_entry_print(State_Machine,true);
  426. network_set_timer(ETH_DHCP_FAIL);
  427. NETWORK_EXECUTE_CB(State_Machine);
  428. messaging_post_message(MESSAGING_INFO, MESSAGING_CLASS_SYSTEM, "Ethernet link up.");
  429. network_handler_entry_print(State_Machine,false);
  430. return EVENT_HANDLED;
  431. }
  432. static state_machine_result_t ETH_ACTIVE_LINKUP_STATE_handler(state_machine_t* const State_Machine) {
  433. state_machine_result_t result = EVENT_UN_HANDLED;
  434. network_handler_print(State_Machine,true);
  435. HANDLE_GLOBAL_EVENT(State_Machine);
  436. network_handler_print(State_Machine,false);
  437. return result;
  438. }
  439. static state_machine_result_t ETH_ACTIVE_LINKUP_STATE_exit_handler(state_machine_t* const State_Machine) {
  440. network_exit_handler_print(State_Machine,true);
  441. network_exit_handler_print(State_Machine,false);
  442. return EVENT_HANDLED;
  443. }
  444. /*********************************************************************************************
  445. * WIFI_UP_STATE
  446. */
  447. static state_machine_result_t NETWORK_WIFI_ACTIVE_STATE_entry_handler(state_machine_t* const State_Machine) {
  448. network_handler_entry_print(State_Machine,true);
  449. NETWORK_EXECUTE_CB(State_Machine);
  450. network_handler_entry_print(State_Machine,false);
  451. return EVENT_HANDLED;
  452. }
  453. static state_machine_result_t NETWORK_WIFI_ACTIVE_STATE_handler(state_machine_t* const State_Machine) {
  454. HANDLE_GLOBAL_EVENT(State_Machine);
  455. network_handler_print(State_Machine,true);
  456. state_machine_result_t result = EVENT_UN_HANDLED;
  457. switch (State_Machine->Event)
  458. {
  459. case EN_LINK_UP:
  460. ESP_LOGW(TAG, "Ethernet link up in wifi mode");
  461. break;
  462. case EN_ETH_GOT_IP:
  463. network_interface_coexistence(State_Machine);
  464. break;
  465. case EN_GOT_IP:
  466. network_status_update_ip_info(UPDATE_CONNECTION_OK);
  467. result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTED_STATE],__FUNCTION__);
  468. break;
  469. case EN_SCAN:
  470. if (network_wifi_start_scan() == ESP_OK) {
  471. result= EVENT_HANDLED;
  472. }
  473. break;
  474. case EN_SCAN_DONE:
  475. if(wifi_scan_done() == ESP_OK) {
  476. result= EVENT_HANDLED;
  477. }
  478. break;
  479. case EN_CONNECT_NEW:
  480. result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTING_NEW_STATE],__FUNCTION__);
  481. break;
  482. case EN_DELETE:
  483. result= local_traverse_state(State_Machine,&Wifi_Active_State[WIFI_USER_DISCONNECTED_STATE],__FUNCTION__);
  484. break;
  485. case EN_ETHERNET_FALLBACK:
  486. result= local_traverse_state(State_Machine, &Eth_Active_State[ETH_ACTIVE_CONNECTED_STATE],__FUNCTION__);
  487. break;
  488. default:
  489. break;
  490. }
  491. network_handler_print(State_Machine,false);
  492. return result;
  493. }
  494. static state_machine_result_t NETWORK_WIFI_ACTIVE_STATE_exit_handler(state_machine_t* const State_Machine) {
  495. network_exit_handler_print(State_Machine,true);
  496. network_exit_handler_print(State_Machine,false);
  497. return EVENT_HANDLED;
  498. }
  499. /*********************************************************************************************
  500. * WIFI_INITIALIZING_STATE
  501. */
  502. static state_machine_result_t WIFI_INITIALIZING_STATE_entry_handler(state_machine_t* const State_Machine) {
  503. network_t* const nm = (network_t *)State_Machine;
  504. network_handler_entry_print(State_Machine,true);
  505. if(!nm->wifi_netif){
  506. nm->wifi_netif = network_wifi_start();
  507. }
  508. if (!is_wifi_up()) {
  509. messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi not started. Load Configuration");
  510. return EVENT_UN_HANDLED;
  511. }
  512. if (network_wifi_get_known_count()>0) {
  513. ESP_LOGI(TAG, "Existing wifi config found. Attempting to connect.");
  514. network_async_success();
  515. } else {
  516. /* no wifi saved: start soft AP! This is what should happen during a first run */
  517. ESP_LOGW(TAG, "No saved wifi. Starting AP configuration mode.");
  518. network_async_configure();
  519. }
  520. NETWORK_EXECUTE_CB(State_Machine);
  521. network_handler_entry_print(State_Machine,false);
  522. return EVENT_HANDLED;
  523. }
  524. static state_machine_result_t WIFI_INITIALIZING_STATE_handler(state_machine_t* const State_Machine) {
  525. HANDLE_GLOBAL_EVENT(State_Machine);
  526. network_handler_print(State_Machine,true);
  527. state_machine_result_t result = EVENT_HANDLED;
  528. switch (State_Machine->Event) {
  529. case EN_CONFIGURE:
  530. result= local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_STATE],__FUNCTION__);
  531. break;
  532. case EN_SUCCESS:
  533. result= local_switch_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTING_STATE],__FUNCTION__);
  534. break;
  535. default:
  536. result= EVENT_UN_HANDLED;
  537. }
  538. network_handler_print(State_Machine,false);
  539. return result;
  540. }
  541. static state_machine_result_t WIFI_INITIALIZING_STATE_exit_handler(state_machine_t* const State_Machine) {
  542. network_exit_handler_print(State_Machine,true);
  543. network_exit_handler_print(State_Machine,false);
  544. return EVENT_HANDLED;
  545. }
  546. /*********************************************************************************************
  547. * WIFI_CONFIGURING_ACTIVE_STATE
  548. */
  549. static state_machine_result_t NETWORK_WIFI_CONFIGURING_ACTIVE_STATE_entry_handler(state_machine_t* const State_Machine) {
  550. network_handler_entry_print(State_Machine,true);
  551. network_t* const nm = (network_t *)State_Machine;
  552. nm->wifi_ap_netif = network_wifi_config_ap();
  553. dns_server_start(nm->wifi_ap_netif);
  554. network_wifi_start_scan();
  555. network_handler_entry_print(State_Machine,false);
  556. return EVENT_HANDLED;
  557. }
  558. static state_machine_result_t NETWORK_WIFI_CONFIGURING_ACTIVE_STATE_handler(state_machine_t* const State_Machine) {
  559. HANDLE_GLOBAL_EVENT(State_Machine);
  560. network_handler_print(State_Machine,true);
  561. state_machine_result_t result = EVENT_HANDLED;
  562. switch (State_Machine->Event) {
  563. case EN_SCAN:
  564. if (network_wifi_start_scan() == ESP_OK) {
  565. result= EVENT_HANDLED;
  566. }
  567. break;
  568. case EN_SCAN_DONE:
  569. ESP_LOGD(TAG,"Network configuration active, wifi scan completed");
  570. if(wifi_scan_done() == ESP_OK) {
  571. result= EVENT_HANDLED;
  572. }
  573. break;
  574. case EN_CONNECT_NEW:
  575. result= local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_CONNECT_STATE],__FUNCTION__);
  576. break;
  577. case EN_LINK_UP:
  578. ESP_LOGW(TAG, "Ethernet link up in wifi mode");
  579. break;
  580. case EN_ETH_GOT_IP:
  581. network_interface_coexistence(State_Machine);
  582. break;
  583. default:
  584. result =EVENT_UN_HANDLED;
  585. }
  586. network_handler_print(State_Machine,false);
  587. return result;
  588. }
  589. static state_machine_result_t NETWORK_WIFI_CONFIGURING_ACTIVE_STATE_exit_handler(state_machine_t* const State_Machine) {
  590. network_exit_handler_print(State_Machine, true);
  591. /* bring down DNS hijack */
  592. ESP_LOGD(TAG, " Stopping DNS.");
  593. dns_server_stop();
  594. ESP_LOGD(TAG, "Changing wifi mode to STA.");
  595. network_wifi_set_sta_mode();
  596. network_exit_handler_print(State_Machine, false);
  597. return EVENT_HANDLED;
  598. }
  599. /*********************************************************************************************
  600. * WIFI_CONFIGURING_STATE
  601. */
  602. static state_machine_result_t WIFI_CONFIGURING_STATE_entry_handler(state_machine_t* const State_Machine) {
  603. network_handler_entry_print(State_Machine,true);
  604. NETWORK_EXECUTE_CB(State_Machine);
  605. network_handler_entry_print(State_Machine,false);
  606. return EVENT_HANDLED;
  607. }
  608. static state_machine_result_t WIFI_CONFIGURING_STATE_handler(state_machine_t* const State_Machine) {
  609. network_handler_print(State_Machine,true);
  610. HANDLE_GLOBAL_EVENT(State_Machine);
  611. network_handler_print(State_Machine,false);
  612. return EVENT_UN_HANDLED;
  613. }
  614. static state_machine_result_t WIFI_CONFIGURING_STATE_exit_handler(state_machine_t* const State_Machine) {
  615. network_exit_handler_print(State_Machine,true);
  616. network_exit_handler_print(State_Machine,false);
  617. return EVENT_HANDLED;
  618. }
  619. /*********************************************************************************************
  620. * WIFI_CONFIGURING_CONNECT_STATE
  621. */
  622. static state_machine_result_t WIFI_CONFIGURING_CONNECT_STATE_entry_handler(state_machine_t* const State_Machine) {
  623. network_t* const nm = (network_t *)State_Machine;
  624. network_handler_entry_print(State_Machine,true);
  625. network_start_stop_dhcp(nm->wifi_netif, true);
  626. network_wifi_connect(nm->event_parameters->ssid,nm->event_parameters->password);
  627. FREE_AND_NULL(nm->event_parameters->ssid);
  628. FREE_AND_NULL(nm->event_parameters->password);
  629. NETWORK_EXECUTE_CB(State_Machine);
  630. network_handler_entry_print(State_Machine,false);
  631. return EVENT_HANDLED;
  632. }
  633. static state_machine_result_t WIFI_CONFIGURING_CONNECT_STATE_handler(state_machine_t* const State_Machine) {
  634. HANDLE_GLOBAL_EVENT(State_Machine);
  635. network_handler_print(State_Machine,true);
  636. state_machine_result_t result = EVENT_HANDLED;
  637. switch (State_Machine->Event) {
  638. case EN_CONNECTED:
  639. result=EVENT_HANDLED;
  640. ESP_LOGD(TAG,"Wifi was connected. Waiting for IP address");
  641. network_set_timer(WIFI_DHCP_FAIL);
  642. break;
  643. case EN_GOT_IP:
  644. network_status_update_ip_info(UPDATE_CONNECTION_OK);
  645. result= local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_CONNECT_SUCCESS_STATE],__FUNCTION__);
  646. break;
  647. case EN_LOST_CONNECTION:
  648. network_status_update_ip_info(UPDATE_FAILED_ATTEMPT);
  649. result = local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_STATE],__FUNCTION__);
  650. break;
  651. default:
  652. result= EVENT_UN_HANDLED;
  653. }
  654. network_handler_print(State_Machine,false);
  655. return result;
  656. }
  657. static state_machine_result_t WIFI_CONFIGURING_CONNECT_STATE_exit_handler(state_machine_t* const State_Machine) {
  658. network_exit_handler_print(State_Machine,true);
  659. FREE_AND_NULL(((network_t *)State_Machine)->event_parameters->disconnected_event);
  660. network_set_timer(0);
  661. network_exit_handler_print(State_Machine,false);
  662. return EVENT_HANDLED;
  663. }
  664. /*********************************************************************************************
  665. * WIFI_CONFIGURING_CONNECT_SUCCESS_STATE
  666. */
  667. static state_machine_result_t WIFI_CONFIGURING_CONNECT_SUCCESS_STATE_entry_handler(state_machine_t* const State_Machine) {
  668. network_handler_entry_print(State_Machine,true);
  669. network_status_update_ip_info(UPDATE_CONNECTION_OK);
  670. ESP_LOGD(TAG, "Saving wifi configuration.");
  671. network_wifi_save_sta_config();
  672. NETWORK_EXECUTE_CB(State_Machine);
  673. network_handler_entry_print(State_Machine,false);
  674. return EVENT_HANDLED;
  675. }
  676. static state_machine_result_t WIFI_CONFIGURING_CONNECT_SUCCESS_STATE_handler(state_machine_t* const State_Machine) {
  677. network_handler_print(State_Machine,true);
  678. state_machine_result_t result = EVENT_HANDLED;
  679. switch (State_Machine->Event) {
  680. case EN_UPDATE_STATUS:
  681. network_status_update_basic_info();
  682. result= local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_CONNECT_SUCCESS_GOTOSTA_STATE],__FUNCTION__);
  683. break;
  684. default:
  685. result= EVENT_UN_HANDLED;
  686. }
  687. // Process global handler at the end, since we want to overwrite
  688. // UPDATE_STATUS with our own logic above
  689. HANDLE_GLOBAL_EVENT(State_Machine);
  690. network_handler_print(State_Machine,false);
  691. return result;
  692. }
  693. static state_machine_result_t WIFI_CONFIGURING_CONNECT_SUCCESS_STATE_exit_handler(state_machine_t* const State_Machine) {
  694. network_exit_handler_print(State_Machine,true);
  695. network_exit_handler_print(State_Machine,false);
  696. return EVENT_HANDLED;
  697. }
  698. /*********************************************************************************************
  699. * WIFI_CONFIGURING_CONNECT_SUCCESS_GOTOSTA_STATE
  700. */
  701. static state_machine_result_t WIFI_CONFIGURING_CONNECT_SUCCESS_GOTOSTA_STATE_entry_handler(state_machine_t* const State_Machine) {
  702. network_handler_entry_print(State_Machine,true);
  703. ESP_LOGD(TAG, "Waiting for next status update event to turn off AP.");
  704. NETWORK_EXECUTE_CB(State_Machine);
  705. network_handler_entry_print(State_Machine,false);
  706. return EVENT_HANDLED;
  707. }
  708. static state_machine_result_t WIFI_CONFIGURING_CONNECT_SUCCESS_GOTOSTA_STATE_handler(state_machine_t* const State_Machine) {
  709. network_handler_print(State_Machine,true);
  710. state_machine_result_t result = EVENT_HANDLED;
  711. switch (State_Machine->Event) {
  712. case EN_UPDATE_STATUS:
  713. network_status_update_basic_info();
  714. result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTED_STATE],__FUNCTION__);
  715. break;
  716. default:
  717. result= EVENT_UN_HANDLED;
  718. }
  719. // Process global handler at the end, since we want to overwrite
  720. // UPDATE_STATUS with our own logic above
  721. HANDLE_GLOBAL_EVENT(State_Machine);
  722. network_handler_print(State_Machine,false);
  723. return result;
  724. }
  725. static state_machine_result_t WIFI_CONFIGURING_CONNECT_SUCCESS_GOTOSTA_STATE_exit_handler(state_machine_t* const State_Machine) {
  726. network_exit_handler_print(State_Machine,true);
  727. network_exit_handler_print(State_Machine,false);
  728. return EVENT_HANDLED;
  729. }
  730. /*********************************************************************************************
  731. * WIFI_CONNECTING_STATE
  732. */
  733. static state_machine_result_t WIFI_CONNECTING_STATE_entry_handler(state_machine_t* const State_Machine) {
  734. network_t* const nm = (network_t *)State_Machine;
  735. network_handler_entry_print(State_Machine,true);
  736. network_start_stop_dhcp(nm->wifi_netif, true);
  737. network_connect_active_ssid(State_Machine);
  738. nm->STA_duration = STA_POLLING_MIN;
  739. /* create timer for background STA connection */
  740. network_set_timer(nm->STA_duration);
  741. NETWORK_EXECUTE_CB(State_Machine);
  742. network_handler_entry_print(State_Machine,false);
  743. return EVENT_HANDLED;
  744. }
  745. static state_machine_result_t WIFI_CONNECTING_STATE_handler(state_machine_t* const State_Machine) {
  746. HANDLE_GLOBAL_EVENT(State_Machine);
  747. state_machine_result_t result = EVENT_HANDLED;
  748. network_handler_print(State_Machine,true);
  749. switch (State_Machine->Event) {
  750. case EN_CONNECTED:
  751. // nothing to do here. Let's wait for IP address
  752. break;
  753. case EN_TIMER:
  754. // try connecting again.
  755. // todo: implement multi-ap logic
  756. network_connect_active_ssid(State_Machine);
  757. break;
  758. default:
  759. result = EVENT_UN_HANDLED;
  760. }
  761. network_handler_print(State_Machine,false);
  762. return result;
  763. }
  764. static state_machine_result_t WIFI_CONNECTING_STATE_exit_handler(state_machine_t* const State_Machine) {
  765. network_exit_handler_print(State_Machine,true);
  766. network_exit_handler_print(State_Machine,false);
  767. return EVENT_HANDLED;
  768. }
  769. /*********************************************************************************************
  770. * WIFI_CONNECTING_NEW_STATE
  771. */
  772. static state_machine_result_t WIFI_CONNECTING_NEW_STATE_entry_handler(state_machine_t* const State_Machine) {
  773. network_t* const nm = (network_t *)State_Machine;
  774. network_handler_entry_print(State_Machine,true);
  775. network_start_stop_dhcp(nm->wifi_netif, true);
  776. network_wifi_connect(nm->event_parameters->ssid,nm->event_parameters->password);
  777. FREE_AND_NULL(nm->event_parameters->ssid);
  778. FREE_AND_NULL(nm->event_parameters->password);
  779. NETWORK_EXECUTE_CB(State_Machine);
  780. network_handler_entry_print(State_Machine,false);
  781. return EVENT_HANDLED;
  782. }
  783. static state_machine_result_t WIFI_CONNECTING_NEW_STATE_handler(state_machine_t* const State_Machine) {
  784. HANDLE_GLOBAL_EVENT(State_Machine);
  785. network_handler_print(State_Machine,true);
  786. state_machine_result_t result = EVENT_HANDLED;
  787. switch (State_Machine->Event) {
  788. case EN_GOT_IP:
  789. network_status_update_ip_info(UPDATE_CONNECTION_OK);
  790. result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTED_STATE],__FUNCTION__);
  791. break;
  792. case EN_CONNECTED:
  793. ESP_LOGD(TAG,"Successfully connected to the new access point. Waiting for IP Address");
  794. result = EVENT_HANDLED;
  795. break;
  796. case EN_LOST_CONNECTION:
  797. if(((network_t *)State_Machine)->event_parameters->disconnected_event->reason == WIFI_REASON_ASSOC_LEAVE){
  798. ESP_LOGD(TAG,"Successfully disconnected from the existing access point. ");
  799. return EVENT_HANDLED;
  800. }
  801. ESP_LOGW(TAG,"Trying to connect failed");
  802. result = local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTING_NEW_FAILED_STATE],__FUNCTION__);
  803. break;
  804. default:
  805. result= EVENT_UN_HANDLED;
  806. }
  807. network_handler_print(State_Machine,false);
  808. return result;
  809. }
  810. static state_machine_result_t WIFI_CONNECTING_NEW_STATE_exit_handler(state_machine_t* const State_Machine) {
  811. network_exit_handler_print(State_Machine,true);
  812. network_set_timer(0);
  813. FREE_AND_NULL(((network_t *)State_Machine)->event_parameters->disconnected_event);
  814. network_exit_handler_print(State_Machine,false);
  815. return EVENT_HANDLED;
  816. }
  817. /*********************************************************************************************
  818. * WIFI_CONNECTING_NEW_FAILED_STATE
  819. */
  820. static state_machine_result_t WIFI_CONNECTING_NEW_FAILED_STATE_entry_handler(state_machine_t* const State_Machine) {
  821. network_t* const nm = (network_t *)State_Machine;
  822. network_handler_entry_print(State_Machine,true);
  823. if (nm->wifi_connected ) {
  824. // Wifi was already connected to an existing access point. Restore connection
  825. network_connect_active_ssid(State_Machine);
  826. }
  827. NETWORK_EXECUTE_CB(State_Machine);
  828. network_handler_entry_print(State_Machine,false);
  829. return EVENT_HANDLED;
  830. }
  831. static state_machine_result_t WIFI_CONNECTING_NEW_FAILED_STATE_handler(state_machine_t* const State_Machine) {
  832. HANDLE_GLOBAL_EVENT(State_Machine);
  833. network_handler_print(State_Machine,true);
  834. state_machine_result_t result = EVENT_HANDLED;
  835. switch (State_Machine->Event) {
  836. case EN_GOT_IP:
  837. network_status_update_ip_info(UPDATE_FAILED_ATTEMPT_AND_RESTORE);
  838. result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTED_STATE],__FUNCTION__);
  839. break;
  840. case EN_CONNECTED:
  841. ESP_LOGD(TAG,"Successfully connected to the previous access point. Waiting for IP Address");
  842. result = EVENT_HANDLED;
  843. break;
  844. case EN_LOST_CONNECTION:
  845. network_status_update_ip_info(UPDATE_FAILED_ATTEMPT);
  846. messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Unable to fall back to previous access point.");
  847. result = EVENT_HANDLED;
  848. break;
  849. default:
  850. result= EVENT_UN_HANDLED;
  851. }
  852. network_handler_print(State_Machine,false);
  853. return result;
  854. }
  855. static state_machine_result_t WIFI_CONNECTING_NEW_FAILED_STATE_exit_handler(state_machine_t* const State_Machine) {
  856. network_exit_handler_print(State_Machine,true);
  857. network_set_timer(0);
  858. FREE_AND_NULL(((network_t *)State_Machine)->event_parameters->disconnected_event);
  859. network_exit_handler_print(State_Machine,false);
  860. return EVENT_HANDLED;
  861. }
  862. /*********************************************************************************************
  863. * WIFI_CONNECTED_STATE
  864. */
  865. static state_machine_result_t WIFI_CONNECTED_STATE_entry_handler(state_machine_t* const State_Machine) {
  866. network_t* const nm = (network_t *)State_Machine;
  867. network_handler_entry_print(State_Machine,true);
  868. nm->last_connected = esp_timer_get_time();
  869. // cancel timeout pulse
  870. network_set_timer(0);
  871. ESP_LOGD(TAG, "Checking if wifi config changed.");
  872. if (network_wifi_sta_config_changed()) {
  873. ESP_LOGD(TAG, "Wifi Config changed. Saving it.");
  874. network_wifi_save_sta_config();
  875. }
  876. ESP_LOGD(TAG, "Updating the ip info json.");
  877. network_interface_coexistence(State_Machine);
  878. nm->wifi_connected = true;
  879. NETWORK_EXECUTE_CB(State_Machine);
  880. network_handler_entry_print(State_Machine,false);
  881. return EVENT_HANDLED;
  882. }
  883. static state_machine_result_t WIFI_CONNECTED_STATE_handler(state_machine_t* const State_Machine) {
  884. HANDLE_GLOBAL_EVENT(State_Machine);
  885. network_handler_print(State_Machine,true);
  886. state_machine_result_t result = EVENT_HANDLED;
  887. switch (State_Machine->Event) {
  888. case EN_LOST_CONNECTION:
  889. result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_LOST_CONNECTION_STATE],__FUNCTION__);
  890. break;
  891. default:
  892. result = EVENT_UN_HANDLED;
  893. break;
  894. }
  895. network_handler_print(State_Machine,false);
  896. return result;
  897. }
  898. static state_machine_result_t WIFI_CONNECTED_STATE_exit_handler(state_machine_t* const State_Machine) {
  899. network_exit_handler_print(State_Machine,true);
  900. FREE_AND_NULL(((network_t *)State_Machine)->event_parameters->disconnected_event);
  901. network_exit_handler_print(State_Machine,false);
  902. return EVENT_HANDLED;
  903. }
  904. /*********************************************************************************************
  905. * WIFI_USER_DISCONNECTED_STATE
  906. */
  907. static state_machine_result_t WIFI_USER_DISCONNECTED_STATE_entry_handler(state_machine_t* const State_Machine) {
  908. network_handler_entry_print(State_Machine,true);
  909. ESP_LOGD(TAG, " WiFi disconnected by user");
  910. network_wifi_clear_config();
  911. network_status_update_ip_info(UPDATE_USER_DISCONNECT);
  912. NETWORK_EXECUTE_CB(State_Machine);
  913. network_handler_entry_print(State_Machine,false);
  914. return EVENT_HANDLED;
  915. }
  916. static state_machine_result_t WIFI_USER_DISCONNECTED_STATE_handler(state_machine_t* const State_Machine) {
  917. HANDLE_GLOBAL_EVENT(State_Machine);
  918. network_handler_print(State_Machine,true);
  919. state_machine_result_t result = EVENT_HANDLED;
  920. switch (State_Machine->Event) {
  921. case EN_LOST_CONNECTION:
  922. // this is a success! we're actually asking to disconnect
  923. result= local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_STATE],__FUNCTION__);
  924. break;
  925. default:
  926. result= EVENT_UN_HANDLED;
  927. }
  928. network_handler_print(State_Machine,false);
  929. return result;
  930. }
  931. static state_machine_result_t WIFI_USER_DISCONNECTED_STATE_exit_handler(state_machine_t* const State_Machine) {
  932. network_exit_handler_print(State_Machine,true);
  933. network_exit_handler_print(State_Machine,false);
  934. return EVENT_HANDLED;
  935. }
  936. /*********************************************************************************************
  937. * WIFI_LOST_CONNECTION_STATE
  938. */
  939. static state_machine_result_t WIFI_LOST_CONNECTION_STATE_entry_handler(state_machine_t* const State_Machine) {
  940. network_t* const nm = (network_t *)State_Machine;
  941. network_handler_entry_print(State_Machine,true);
  942. ESP_LOGE(TAG, " WiFi Connection lost.");
  943. messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "WiFi Connection lost");
  944. network_status_update_ip_info(UPDATE_LOST_CONNECTION);
  945. network_status_safe_reset_sta_ip_string();
  946. if (nm->last_connected > 0)
  947. nm->total_connected_time += ((esp_timer_get_time() - nm->last_connected) / (1000 * 1000));
  948. nm->last_connected = 0;
  949. nm->num_disconnect++;
  950. ESP_LOGW(TAG, " Wifi disconnected. Number of disconnects: %d, Average time connected: %d", nm->num_disconnect, nm->num_disconnect > 0 ? (nm->total_connected_time / nm->num_disconnect) : 0);
  951. if (nm->retries < WIFI_MANAGER_MAX_RETRY) {
  952. nm->retries++;
  953. ESP_LOGD(TAG, " Retrying connection connection, %d/%d.", nm->retries, WIFI_MANAGER_MAX_RETRY);
  954. network_connect_active_ssid( State_Machine);
  955. } else {
  956. /* In this scenario the connection was lost beyond repair */
  957. nm->retries = 0;
  958. ESP_LOGD(TAG,"Checking if ethernet interface is connected");
  959. if (network_is_interface_connected(nm->eth_netif)) {
  960. ESP_LOGW(TAG, "Cannot connect to Wifi. Falling back to Ethernet ");
  961. network_async(EN_ETHERNET_FALLBACK);
  962. } else {
  963. network_status_update_ip_info(UPDATE_LOST_CONNECTION);
  964. wifi_mode_t mode;
  965. ESP_LOGW(TAG, " All connect retry attempts failed.");
  966. /* put us in softAP mode first */
  967. esp_wifi_get_mode(&mode);
  968. if (WIFI_MODE_APSTA != mode) {
  969. nm->STA_duration = STA_POLLING_MIN;
  970. network_async_configure();
  971. } else if (nm->STA_duration < STA_POLLING_MAX) {
  972. nm->STA_duration *= 1.25;
  973. }
  974. /* keep polling for existing connection */
  975. network_set_timer(nm->STA_duration);
  976. ESP_LOGD(TAG, " STA search slow polling of %d", nm->STA_duration);
  977. }
  978. }
  979. NETWORK_EXECUTE_CB(State_Machine);
  980. network_handler_entry_print(State_Machine,false);
  981. return EVENT_HANDLED;
  982. }
  983. static state_machine_result_t WIFI_LOST_CONNECTION_STATE_handler(state_machine_t* const State_Machine) {
  984. HANDLE_GLOBAL_EVENT(State_Machine);
  985. state_machine_result_t result = EVENT_HANDLED;
  986. network_handler_print(State_Machine,true);
  987. switch (State_Machine->Event) {
  988. case EN_CONFIGURE:
  989. result= local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_STATE],__FUNCTION__);
  990. break;
  991. case EN_TIMER:
  992. result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_LOST_CONNECTION_STATE],__FUNCTION__);
  993. break;
  994. case EN_CONNECT:
  995. result= local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONNECTING_STATE],__FUNCTION__);
  996. break;
  997. default:
  998. result= EVENT_UN_HANDLED;
  999. }
  1000. network_handler_print(State_Machine,false);
  1001. return result;
  1002. }
  1003. static state_machine_result_t WIFI_LOST_CONNECTION_STATE_exit_handler(state_machine_t* const State_Machine) {
  1004. network_exit_handler_print(State_Machine,true);
  1005. network_exit_handler_print(State_Machine,false);
  1006. return EVENT_HANDLED;
  1007. }
  1008. /*********************************************************************************************
  1009. * ETH_ACTIVE_CONNECTED_STATE
  1010. */
  1011. static state_machine_result_t ETH_ACTIVE_CONNECTED_STATE_entry_handler(state_machine_t* const State_Machine) {
  1012. network_t* const nm = (network_t *)State_Machine;
  1013. network_handler_entry_print(State_Machine,true);
  1014. network_status_update_ip_info(UPDATE_ETHERNET_CONNECTED);
  1015. nm->ethernet_connected = true;
  1016. // start a wifi Scan so web ui is populated with available entries
  1017. NETWORK_EXECUTE_CB(State_Machine);
  1018. network_handler_entry_print(State_Machine,false);
  1019. return EVENT_HANDLED;
  1020. }
  1021. static state_machine_result_t ETH_ACTIVE_CONNECTED_STATE_handler(state_machine_t* const State_Machine) {
  1022. HANDLE_GLOBAL_EVENT(State_Machine);
  1023. state_machine_result_t result = EVENT_HANDLED;
  1024. network_handler_print(State_Machine,true);
  1025. switch (State_Machine->Event) {
  1026. case EN_TIMER:
  1027. ESP_LOGD(TAG, "Ignoring ethernet link up timer check");
  1028. result= EVENT_HANDLED;
  1029. break;
  1030. default:
  1031. result= EVENT_UN_HANDLED;
  1032. }
  1033. network_handler_print(State_Machine,false);
  1034. return result;
  1035. }
  1036. static state_machine_result_t ETH_ACTIVE_CONNECTED_STATE_exit_handler(state_machine_t* const State_Machine) {
  1037. network_exit_handler_print(State_Machine,true);
  1038. network_exit_handler_print(State_Machine,false);
  1039. return EVENT_HANDLED;
  1040. }
  1041. static state_machine_result_t local_switch_state(state_machine_t* state_machine,
  1042. const state_t* const target_state, const char * caller) {
  1043. const state_t* source = state_machine->State;
  1044. NETWORK_PRINT_TRANSITION(true, "BEGIN SWITCH", ((network_t *)state_machine)->source_state, target_state, state_machine->Event, true,caller);
  1045. state_machine_result_t result = switch_state(state_machine, target_state);
  1046. NETWORK_PRINT_TRANSITION( false,"BEGIN SWITCH", ((network_t *)state_machine)->source_state, target_state, state_machine->Event, true,caller);
  1047. ((network_t *)state_machine)->source_state = source;
  1048. return result;
  1049. }
  1050. static state_machine_result_t local_traverse_state(state_machine_t* const state_machine,
  1051. const state_t* const target_state, const char * caller) {
  1052. const state_t * source = state_machine->State;
  1053. NETWORK_PRINT_TRANSITION( true,"BEGIN TRAVERSE", ((network_t *)state_machine)->source_state, target_state, state_machine->Event, true, caller);
  1054. state_machine_result_t result = traverse_state(state_machine, target_state);
  1055. NETWORK_PRINT_TRANSITION( false,"END TRAVERSE", ((network_t *)state_machine)->source_state, target_state, state_machine->Event, true,caller);
  1056. ((network_t *)state_machine)->source_state = source;
  1057. return result;
  1058. }
  1059. static void network_interface_coexistence(state_machine_t* state_machine) {
  1060. // this function is called whenever both wifi and ethernet are
  1061. // found to be active at the same time
  1062. network_t* nm = (network_t *)state_machine;
  1063. if (nm->wifi_connected && state_machine->Event == EN_ETH_GOT_IP) {
  1064. char* eth_reboot = config_alloc_get_default(NVS_TYPE_STR, "eth_boot", "N", 0);
  1065. network_prioritize_wifi(false);
  1066. if (strcasecmp(eth_reboot, "N")) {
  1067. ESP_LOGW(TAG, "Option eth_reboot set to reboot when ethernet is connected. Rebooting");
  1068. simple_restart();
  1069. } else {
  1070. ESP_LOGW(TAG, "Option eth_reboot set to not reboot when ethernet is connected. Using Wifi interface until next reboot");
  1071. }
  1072. FREE_AND_NULL(eth_reboot);
  1073. } else if (get_root(state_machine->State)->Id == NETWORK_ETH_ACTIVE_STATE){
  1074. messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi Connected with Ethernet active. System reload needed");
  1075. simple_restart();
  1076. }
  1077. }