_WiFi.ino 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. // 1-channel LoRa Gateway for ESP8266
  2. // Copyright (c) 2016-2020 Maarten Westenberg version for ESP8266
  3. //
  4. // based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
  5. // and many others.
  6. //
  7. // All rights reserved. This program and the accompanying materials
  8. // are made available under the terms of the MIT License
  9. // which accompanies this distribution, and is available at
  10. // https://opensource.org/licenses/mit-license.php
  11. //
  12. // NO WARRANTY OF ANY KIND IS PROVIDED
  13. //
  14. // Author: Maarten Westenberg (mw12554@hotmail.com)
  15. //
  16. // This file contains the LoRa filesystem specific code
  17. // ----------------------------------------------------------------------------
  18. // WLANSTATUS prints the status of the Wlan.
  19. // The status of the Wlan "connection" can change if we have no relation
  20. // with the well known router anymore. Normally this relation is preserved
  21. // but sometimes we have to reconfirm to the router again and we get the same
  22. // address too.
  23. // So, if the router is still in range we can "survive" with the same address
  24. // and we may have to renew the "connection" from time to time.
  25. // But when we loose the SSID connection, we may have to look for another router.
  26. //
  27. // Parameters: <none>
  28. // Return value: Returns 1 when still WL_CONNETED, otherwise returns 0
  29. // ----------------------------------------------------------------------------
  30. int WlanStatus() {
  31. switch (WiFi.status()) {
  32. case WL_CONNECTED:
  33. # if _MONITOR>=1
  34. if ( debug>=1 ) {
  35. mPrint("WlanStatus:: CONNECTED ssid=" + String(WiFi.SSID())); // 3
  36. }
  37. # endif //_MONITOR
  38. WiFi.setAutoReconnect(true); // Reconect to this AP if DISCONNECTED
  39. return(1);
  40. break;
  41. // In case we get disconnected from the AP we lose the IP address.
  42. // The ESP is configured to reconnect to the last router in memory.
  43. case WL_DISCONNECTED:
  44. # if _MONITOR>=1
  45. if ( debug>=0 ) {
  46. mPrint("WlanStatus:: DISCONNECTED, IP=" + String(WiFi.localIP().toString())); // 6
  47. }
  48. # endif
  49. //while (! WiFi.isConnected() ) {
  50. delay(100);
  51. //}
  52. return(0);
  53. break;
  54. // When still pocessing
  55. case WL_IDLE_STATUS:
  56. # if _MONITOR>=1
  57. if ( debug>=0 ) {
  58. mPrint("WlanStatus:: IDLE"); // 0
  59. }
  60. # endif //_MONITOR
  61. break;
  62. // This code is generated as soonas the AP is out of range
  63. // Whene detected, the program will search for a better AP in range
  64. case WL_NO_SSID_AVAIL:
  65. # if _MONITOR>=1
  66. if ( debug>=0 )
  67. mPrint("WlanStatus:: NO SSID"); // 1
  68. # endif //_MONITOR
  69. break;
  70. case WL_CONNECT_FAILED:
  71. # if _MONITOR>=1
  72. if ( debug>=0 )
  73. mPrint("WlanStatus:: Connect FAILED"); // 4
  74. # endif //_MONITOR
  75. break;
  76. // Never seen this code
  77. case WL_SCAN_COMPLETED:
  78. # if _MONITOR>=1
  79. if ( debug>=0 )
  80. mPrint("WlanStatus:: SCAN COMPLETE"); // 2
  81. # endif //_MONITOR
  82. break;
  83. // Never seen this code
  84. case WL_CONNECTION_LOST:
  85. # if _MONITOR>=1
  86. if ( debug>=0 )
  87. mPrint("WlanStatus:: Connection LOST"); // 5
  88. # endif //_MONITOR
  89. break;
  90. // This code is generated for example when WiFi.begin() has not been called
  91. // before accessing WiFi functions
  92. case WL_NO_SHIELD:
  93. # if _MONITOR>=1
  94. if ( debug>=0 )
  95. mPrint("WlanStatus:: WL_NO_SHIELD"); //
  96. # endif //_MONITOR
  97. break;
  98. default:
  99. # if _MONITOR>=1
  100. if ( debug>=0 ) {
  101. mPrint("WlanStatus Error:: code=" + String(WiFi.status())); // 255 means ERROR
  102. }
  103. # endif //_MONITOR
  104. break;
  105. }
  106. return(-1);
  107. } // WlanStatus
  108. // ----------------------------------------------------------------------------
  109. // When ESP WiFi Manager, do this
  110. // ----------------------------------------------------------------------------
  111. int wifiMgr()
  112. {
  113. #if _WIFIMANAGER==1
  114. ESP_WiFiManager ESP_wifiManager;
  115. # if _MONITOR>=1
  116. if (debug>=1) {
  117. mPrint("Starting Access Point Mode");
  118. mPrint("Connect Wifi to accesspoint: "+String(AP_NAME)+" and connect to IP: 192.168.4.1");
  119. }
  120. # endif //_MONITOR
  121. // Add the ID to the SSID of the WiFiManager
  122. String ssid = String(AP_NAME) + "-" + String(ESP_getChipId(), HEX);
  123. char s [ssid.length() + 1];
  124. strncpy(s, ssid.c_str(), ssid.length());
  125. s[ssid.length()]= 0;
  126. ESP_wifiManager.setConfigPortalTimeout(120);
  127. ESP_wifiManager.startConfigPortal(s, AP_PASSWD );
  128. # if _MONITOR>=1
  129. if ((debug>=1) && (pdebug & P_MAIN)) {
  130. mPrint("WlanConnect:: Now starting WlanStatus");
  131. delay(1);
  132. int i = WlanStatus();
  133. switch (i) {
  134. case 1: mPrint("WlanConnect:: WlanStatus Connected"); break;
  135. case 0: mPrint("WlanConnect:: WlanStatus Disconnected"); break;
  136. default: mPrint("WlatConnect:: WlanStatus other");
  137. }
  138. }
  139. # endif //_MONITOR
  140. // At this point, there IS a Wifi Access Point found and connected
  141. // We must connect to the local SPIFFS storage to store the access point
  142. //String s = WiFi.SSID();
  143. # if defined(ESP32_ARCH)
  144. //
  145. # else
  146. // Now look for the password
  147. struct station_config sta_conf;
  148. wifi_station_get_config(&sta_conf);
  149. # endif //ESP32_ARCH
  150. #endif //_WIFIMANAGER
  151. return 1;
  152. }
  153. // ----------------------------------------------------------------------------
  154. // Function to join the Wifi Network (as defined in sta array
  155. // It is a matter of returning to the main loop() asap and make sure in next loop
  156. // the reconnect is done first thing. By default the system will reconnect to the
  157. // samen SSID as it was connected to before.
  158. // Parameters:
  159. // int maxTry: Number of retries we do:
  160. // 0: Used during Setup first CONNECT
  161. // 1: Try once and if unsuccessful return(1);
  162. // x: Try x times
  163. //
  164. // Returns:
  165. // On failure: Return -1
  166. // On connect: return 1
  167. // On Disconnect state: return 0
  168. //
  169. // XXX After a few retries, the ESP should be reset. Note: Switching between
  170. // two SSID's does the trick. Retrying the same SSID does not.
  171. // Workaround is found below: Let the ESP forget the SSID
  172. //
  173. // NOTE: The Serial works only on debug setting and not on pdebug. This is
  174. // because WiFi problems would make webserver (which works on WiFi) useless.
  175. // ----------------------------------------------------------------------------
  176. int WlanConnect(int maxTry) {
  177. unsigned char agains = 0;
  178. unsigned char wpa_index = 0;
  179. // WiFi.persistent(false);
  180. // WiFi.mode(WIFI_OFF); // this is a temporary line, to be removed after SDK update to 1.5.4
  181. // Else: try to connect to WLAN as long as we are not connected.
  182. // The try parameters tells us how many times we try before giving up
  183. // Value 0 is reserved for setup() first time connect
  184. int i=0;
  185. while ( (WiFi.status() != WL_CONNECTED) && (( i<= maxTry ) || (maxTry==0)) )
  186. {
  187. // We try every SSID in wpa array until success
  188. for (int j=wpa_index; (j< (sizeof(wpa)/sizeof(wpa[0]))) && (WiFi.status() != WL_CONNECTED ); j++)
  189. {
  190. // Start with well-known access points in the list
  191. char *ssid = wpa[j].login;
  192. char *password = wpa[j].passw;
  193. # if _MONITOR>=1
  194. if (debug>=1) {
  195. Serial.print(i);
  196. Serial.print(':');
  197. Serial.print(j);
  198. Serial.print(':');
  199. Serial.print(sizeof(wpa)/sizeof(wpa[0]));
  200. Serial.print(F(". WlanConnect SSID="));
  201. Serial.print(ssid);
  202. if ( debug>=2 ) {
  203. Serial.print(F(", pass="));
  204. Serial.print(password);
  205. }
  206. Serial.println();
  207. }
  208. # endif //_MONITOR
  209. // Count the number of times we call WiFi.begin
  210. gwayConfig.wifis++;
  211. WiFi.mode(WIFI_STA);
  212. delay(1000);
  213. WiFi.begin(ssid, password);
  214. delay(8000);
  215. // Check the connection status again, return values
  216. // 1 = CONNECTED
  217. // 0 = DISCONNECTED (will reconnect)
  218. // -1 = No SSID or other cause
  219. int stat = WlanStatus();
  220. if ( stat == 1) {
  221. writeGwayCfg(CONFIGFILE, &gwayConfig ); // Write configuration to SPIFFS
  222. return(1);
  223. }
  224. // We increase the time for connect but try the same SSID
  225. // We try for several times
  226. agains=1;
  227. while (((WiFi.status()) != WL_CONNECTED) && (agains < 8)) {
  228. agains++;
  229. delay(8000); //delay(agains*500);
  230. # if _MONITOR>=1
  231. if ( debug>=0 ) {
  232. Serial.print("."); // Serial only
  233. }
  234. # endif //_MONITOR
  235. }
  236. // Make sure that we can connect to different AP's than 1
  237. // this is a patch. Normally we connect to previous one.
  238. WiFi.persistent(false);
  239. WiFi.mode(WIFI_OFF); // this is a temporary line, to be removed after SDK update to 1.5.4
  240. } //for next WPA defined AP
  241. i++; // Number of times we try to connect
  242. } //while
  243. # if _MONITOR>=1
  244. if ((debug>=2) & (pdebug & P_MAIN)) {
  245. mPrint("WlanConnect:: Connected="+ String(WiFi.SSID()) );
  246. }
  247. # endif //_MONITOR
  248. yield();
  249. return(1);
  250. } //WlanConnect
  251. // ----------------------------------------------------------------------------
  252. // resolveHost
  253. // This function will use MDNS or DNS to resolve a hostname.
  254. // So it may be .local or a normal hostname.
  255. // Parameters:
  256. // svrName: Name of the server we want the IP address from
  257. // maxTry: The number we triue to get the value. 0 means: wait forever.
  258. // Return:
  259. // svrIP: 4 byte IP address of machine resolved
  260. // ----------------------------------------------------------------------------
  261. IPAddress resolveHost(String svrName, int maxTry)
  262. {
  263. IPAddress svrIP;
  264. if (svrName.endsWith(".local")) {
  265. # if defined(ESP32_ARCH)
  266. svrName=svrName.substring(0,svrName.length()-6);
  267. svrIP = MDNS.queryHost(svrName);
  268. for (byte i=0; i<maxTry; i++) { // Try 5 times MDNS
  269. svrIP = MDNS.queryHost(svrName);
  270. if (svrIP.toString() != "0.0.0.0") break;
  271. # if (_MONITOR>=1)
  272. mPrint("ReTrying to resolve with mDNS");
  273. # endif //_MONITOR
  274. delay(12000);
  275. }
  276. # else
  277. char cc[svrName.length() +1 ];
  278. strncpy(cc, svrName.c_str(),svrName.length());
  279. cc[svrName.length()]=0;
  280. for (byte i=0; i<maxTry; i++) {
  281. if (!WiFi.hostByName(cc, svrIP)) // Use DNS to get server IP once
  282. {
  283. mPrint("resolveHost:: ERROR hostByName="+ String(cc)+", len=" + String(sizeof(cc)));
  284. };
  285. delay(1000);
  286. }
  287. # if _MONITOR>=1
  288. if ((debug>=1) && (pdebug & P_MAIN)) {
  289. mPrint("resolveHost:: "+ String(cc) +" IP=" + String(svrIP.toString()) );
  290. }
  291. # endif //_MONITOR
  292. # endif
  293. }
  294. else // Non LOCAL
  295. {
  296. char cc[svrName.length() +1 ]; // Assume whole array initially 0
  297. strncpy(cc, svrName.c_str(),svrName.length());
  298. cc[svrName.length()]=0;
  299. for (byte i=0; i<maxTry; i++) {
  300. if (WiFi.hostByName(cc, svrIP)) // Use DNS to get server IP once
  301. {
  302. # if _MONITOR>=1
  303. mPrint("resolveHost:: OK="+ String(cc) +" IP=" + String(svrIP.toString()) );
  304. # endif //_MONITOR
  305. return svrIP; // If connected
  306. }
  307. else // Else not connected
  308. {
  309. mPrint("resolveHost:: ERROR hostByName="+ String(cc)+", len=" + String(sizeof(cc)));
  310. };
  311. delay(1000);
  312. }
  313. }
  314. return svrIP;
  315. }