network_manager_handlers.c 50 KB

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